From 03f8528315fa46c95991a34f3325d7b33ae5538c Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Sat, 02 May 2020 21:48:36 +0000
Subject: [PATCH] Update source to SDL2 2.0.12
---
source/src/render/opengles/SDL_render_gles.c | 1167 +++++++++++++++++++++++++++++-----------------------------
1 files changed, 581 insertions(+), 586 deletions(-)
diff --git a/source/src/render/opengles/SDL_render_gles.c b/source/src/render/opengles/SDL_render_gles.c
index 4007dff..044a1be 100644
--- a/source/src/render/opengles/SDL_render_gles.c
+++ b/source/src/render/opengles/SDL_render_gles.c
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
- Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+ Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -22,12 +22,13 @@
#if SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED
+#include "SDL_assert.h"
#include "SDL_hints.h"
#include "SDL_opengles.h"
#include "../SDL_sysrender.h"
-/* To prevent unnecessary window recreation,
- * these should match the defaults selected in SDL_GL_ResetAttributes
+/* To prevent unnecessary window recreation,
+ * these should match the defaults selected in SDL_GL_ResetAttributes
*/
#define RENDERER_CONTEXT_MAJOR 1
@@ -52,45 +53,6 @@
static const float inv255f = 1.0f / 255.0f;
-static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags);
-static void GLES_WindowEvent(SDL_Renderer * renderer,
- const SDL_WindowEvent *event);
-static int GLES_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
-static SDL_bool GLES_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode);
-static int GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
-static int GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
- const SDL_Rect * rect, const void *pixels,
- int pitch);
-static int GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
- const SDL_Rect * rect, void **pixels, int *pitch);
-static void GLES_UnlockTexture(SDL_Renderer * renderer,
- SDL_Texture * texture);
-static int GLES_SetRenderTarget(SDL_Renderer * renderer,
- SDL_Texture * texture);
-static int GLES_UpdateViewport(SDL_Renderer * renderer);
-static int GLES_UpdateClipRect(SDL_Renderer * renderer);
-static int GLES_RenderClear(SDL_Renderer * renderer);
-static int GLES_RenderDrawPoints(SDL_Renderer * renderer,
- const SDL_FPoint * points, int count);
-static int GLES_RenderDrawLines(SDL_Renderer * renderer,
- const SDL_FPoint * points, int count);
-static int GLES_RenderFillRects(SDL_Renderer * renderer,
- const SDL_FRect * rects, int count);
-static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
- const SDL_Rect * srcrect,
- const SDL_FRect * dstrect);
-static int GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
- const SDL_Rect * srcrect, const SDL_FRect * dstrect,
- const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
-static int GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
- Uint32 pixel_format, void * pixels, int pitch);
-static void GLES_RenderPresent(SDL_Renderer * renderer);
-static void GLES_DestroyTexture(SDL_Renderer * renderer,
- SDL_Texture * texture);
-static void GLES_DestroyRenderer(SDL_Renderer * renderer);
-static int GLES_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh);
-static int GLES_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture);
-
typedef struct GLES_FBOList GLES_FBOList;
struct GLES_FBOList
@@ -100,26 +62,27 @@
GLES_FBOList *next;
};
-
-SDL_RenderDriver GLES_RenderDriver = {
- GLES_CreateRenderer,
- {
- "opengles",
- (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),
- 1,
- {SDL_PIXELFORMAT_ABGR8888},
- 0,
- 0}
-};
+typedef struct
+{
+ SDL_Rect viewport;
+ SDL_bool viewport_dirty;
+ SDL_Texture *texture;
+ SDL_Texture *target;
+ int drawablew;
+ int drawableh;
+ SDL_BlendMode blend;
+ SDL_bool cliprect_enabled_dirty;
+ SDL_bool cliprect_enabled;
+ SDL_bool cliprect_dirty;
+ SDL_Rect cliprect;
+ SDL_bool texturing;
+ Uint32 color;
+ Uint32 clear_color;
+} GLES_DrawStateCache;
typedef struct
{
SDL_GLContext context;
- struct {
- Uint32 color;
- SDL_BlendMode blendMode;
- SDL_bool tex_coords;
- } current;
#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
#define SDL_PROC_OES SDL_PROC
@@ -133,6 +96,8 @@
SDL_bool GL_OES_blend_func_separate_supported;
SDL_bool GL_OES_blend_equation_separate_supported;
SDL_bool GL_OES_blend_subtract_supported;
+
+ GLES_DrawStateCache drawstate;
} GLES_RenderData;
typedef struct
@@ -206,7 +171,7 @@
#define SDL_PROC_OES(ret,func,params) \
do { \
data->func = SDL_GL_GetProcAddress(#func); \
- } while ( 0 );
+ } while ( 0 );
#endif /* __SDL_NOGETPROCADDR__ */
#include "SDL_glesfuncs.h"
@@ -214,8 +179,6 @@
#undef SDL_PROC_OES
return 0;
}
-
-static SDL_GLContext SDL_CurrentContext = NULL;
static GLES_FBOList *
GLES_GetFBO(GLES_RenderData *data, Uint32 w, Uint32 h)
@@ -241,191 +204,19 @@
{
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
- if (SDL_CurrentContext != data->context) {
+ if (SDL_GL_GetCurrentContext() != data->context) {
if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
return -1;
}
- SDL_CurrentContext = data->context;
-
- GLES_UpdateViewport(renderer);
}
+
return 0;
-}
-
-/* This is called if we need to invalidate all of the SDL OpenGL state */
-static void
-GLES_ResetState(SDL_Renderer *renderer)
-{
- GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-
- if (SDL_CurrentContext == data->context) {
- GLES_UpdateViewport(renderer);
- } else {
- GLES_ActivateRenderer(renderer);
- }
-
- data->current.color = 0xffffffff;
- data->current.blendMode = SDL_BLENDMODE_INVALID;
- data->current.tex_coords = SDL_FALSE;
-
- data->glDisable(GL_DEPTH_TEST);
- data->glDisable(GL_CULL_FACE);
-
- data->glMatrixMode(GL_MODELVIEW);
- data->glLoadIdentity();
-
- data->glEnableClientState(GL_VERTEX_ARRAY);
- data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-}
-
-SDL_Renderer *
-GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
-{
-
- SDL_Renderer *renderer;
- GLES_RenderData *data;
- GLint value;
- Uint32 window_flags;
- int profile_mask = 0, major = 0, minor = 0;
- SDL_bool changed_window = SDL_FALSE;
-
- SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_mask);
- SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
- SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
-
- window_flags = SDL_GetWindowFlags(window);
- if (!(window_flags & SDL_WINDOW_OPENGL) ||
- profile_mask != SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
-
- changed_window = SDL_TRUE;
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, RENDERER_CONTEXT_MAJOR);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, RENDERER_CONTEXT_MINOR);
-
- if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
- goto error;
- }
- }
-
- renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
- if (!renderer) {
- SDL_OutOfMemory();
- goto error;
- }
-
- data = (GLES_RenderData *) SDL_calloc(1, sizeof(*data));
- if (!data) {
- GLES_DestroyRenderer(renderer);
- SDL_OutOfMemory();
- goto error;
- }
-
- renderer->WindowEvent = GLES_WindowEvent;
- renderer->GetOutputSize = GLES_GetOutputSize;
- renderer->SupportsBlendMode = GLES_SupportsBlendMode;
- renderer->CreateTexture = GLES_CreateTexture;
- renderer->UpdateTexture = GLES_UpdateTexture;
- renderer->LockTexture = GLES_LockTexture;
- renderer->UnlockTexture = GLES_UnlockTexture;
- renderer->SetRenderTarget = GLES_SetRenderTarget;
- renderer->UpdateViewport = GLES_UpdateViewport;
- renderer->UpdateClipRect = GLES_UpdateClipRect;
- renderer->RenderClear = GLES_RenderClear;
- renderer->RenderDrawPoints = GLES_RenderDrawPoints;
- renderer->RenderDrawLines = GLES_RenderDrawLines;
- renderer->RenderFillRects = GLES_RenderFillRects;
- renderer->RenderCopy = GLES_RenderCopy;
- renderer->RenderCopyEx = GLES_RenderCopyEx;
- renderer->RenderReadPixels = GLES_RenderReadPixels;
- renderer->RenderPresent = GLES_RenderPresent;
- renderer->DestroyTexture = GLES_DestroyTexture;
- renderer->DestroyRenderer = GLES_DestroyRenderer;
- renderer->GL_BindTexture = GLES_BindTexture;
- renderer->GL_UnbindTexture = GLES_UnbindTexture;
- renderer->info = GLES_RenderDriver.info;
- renderer->info.flags = SDL_RENDERER_ACCELERATED;
- renderer->driverdata = data;
- renderer->window = window;
-
- data->context = SDL_GL_CreateContext(window);
- if (!data->context) {
- GLES_DestroyRenderer(renderer);
- goto error;
- }
- if (SDL_GL_MakeCurrent(window, data->context) < 0) {
- GLES_DestroyRenderer(renderer);
- goto error;
- }
-
- if (GLES_LoadFunctions(data) < 0) {
- GLES_DestroyRenderer(renderer);
- goto error;
- }
-
- if (flags & SDL_RENDERER_PRESENTVSYNC) {
- SDL_GL_SetSwapInterval(1);
- } else {
- SDL_GL_SetSwapInterval(0);
- }
- if (SDL_GL_GetSwapInterval() > 0) {
- renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
- }
-
- value = 0;
- data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
- renderer->info.max_texture_width = value;
- value = 0;
- data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
- renderer->info.max_texture_height = value;
-
- /* Android does not report GL_OES_framebuffer_object but the functionality seems to be there anyway */
- if (SDL_GL_ExtensionSupported("GL_OES_framebuffer_object") || data->glGenFramebuffersOES) {
- data->GL_OES_framebuffer_object_supported = SDL_TRUE;
- renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
-
- value = 0;
- data->glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &value);
- data->window_framebuffer = (GLuint)value;
- }
- data->framebuffers = NULL;
-
- if (SDL_GL_ExtensionSupported("GL_OES_blend_func_separate")) {
- data->GL_OES_blend_func_separate_supported = SDL_TRUE;
- }
- if (SDL_GL_ExtensionSupported("GL_OES_blend_equation_separate")) {
- data->GL_OES_blend_equation_separate_supported = SDL_TRUE;
- }
- if (SDL_GL_ExtensionSupported("GL_OES_blend_subtract")) {
- data->GL_OES_blend_subtract_supported = SDL_TRUE;
- }
-
- /* Set up parameters for rendering */
- GLES_ResetState(renderer);
-
- return renderer;
-
-error:
- if (changed_window) {
- /* Uh oh, better try to put it back... */
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile_mask);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
- SDL_RecreateWindow(window, window_flags);
- }
- return NULL;
}
static void
GLES_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
{
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-
- if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
- event->event == SDL_WINDOWEVENT_SHOWN ||
- event->event == SDL_WINDOWEVENT_HIDDEN) {
- /* Rebind the context to the window area and update matrices */
- SDL_CurrentContext = NULL;
- }
if (event->event == SDL_WINDOWEVENT_MINIMIZED) {
/* According to Apple documentation, we need to finish drawing NOW! */
@@ -561,7 +352,7 @@
}
}
-
+
if (texture->access == SDL_TEXTUREACCESS_TARGET) {
if (!renderdata->GL_OES_framebuffer_object_supported) {
SDL_free(data);
@@ -571,7 +362,7 @@
} else {
data->fbo = NULL;
}
-
+
renderdata->glGetError();
renderdata->glEnable(GL_TEXTURE_2D);
@@ -601,13 +392,15 @@
renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
texture_h, 0, format, type, NULL);
renderdata->glDisable(GL_TEXTURE_2D);
+ renderdata->drawstate.texture = texture;
+ renderdata->drawstate.texturing = SDL_FALSE;
result = renderdata->glGetError();
if (result != GL_NO_ERROR) {
SDL_free(data);
return GLES_SetError("glTexImage2D()", result);
}
-
+
texture->driverdata = data;
return 0;
}
@@ -664,6 +457,9 @@
renderdata->glDisable(data->type);
SDL_free(blob);
+ renderdata->drawstate.texture = texture;
+ renderdata->drawstate.texturing = SDL_FALSE;
+
if (renderdata->glGetError() != GL_NO_ERROR) {
return SDL_SetError("Failed to update texture");
}
@@ -697,6 +493,18 @@
GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch);
}
+static void
+GLES_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode)
+{
+ GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
+ GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
+ GLenum glScaleMode = (scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR;
+
+ renderdata->glBindTexture(data->type, data->texture);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, glScaleMode);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, glScaleMode);
+}
+
static int
GLES_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
{
@@ -707,6 +515,8 @@
if (!data->GL_OES_framebuffer_object_supported) {
return SDL_SetError("Can't enable render target support in this renderer");
}
+
+ data->drawstate.viewport_dirty = SDL_TRUE;
if (texture == NULL) {
data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, data->window_framebuffer);
@@ -725,293 +535,77 @@
return 0;
}
+
static int
-GLES_UpdateViewport(SDL_Renderer * renderer)
+GLES_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
{
- GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-
- if (SDL_CurrentContext != data->context) {
- /* We'll update the viewport after we rebind the context */
- return 0;
- }
-
- if (renderer->target) {
- data->glViewport(renderer->viewport.x, renderer->viewport.y,
- renderer->viewport.w, renderer->viewport.h);
- } else {
- int w, h;
-
- SDL_GL_GetDrawableSize(renderer->window, &w, &h);
- data->glViewport(renderer->viewport.x, (h - renderer->viewport.y - renderer->viewport.h),
- renderer->viewport.w, renderer->viewport.h);
- }
-
- data->glMatrixMode(GL_PROJECTION);
- data->glLoadIdentity();
- if (renderer->viewport.w && renderer->viewport.h) {
- if (renderer->target) {
- data->glOrthof((GLfloat) 0,
- (GLfloat) renderer->viewport.w,
- (GLfloat) 0,
- (GLfloat) renderer->viewport.h,
- 0.0, 1.0);
- } else {
- data->glOrthof((GLfloat) 0,
- (GLfloat) renderer->viewport.w,
- (GLfloat) renderer->viewport.h,
- (GLfloat) 0,
- 0.0, 1.0);
- }
- }
- data->glMatrixMode(GL_MODELVIEW);
-
- return 0;
+ return 0; /* nothing to do in this backend. */
}
static int
-GLES_UpdateClipRect(SDL_Renderer * renderer)
+GLES_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
{
- GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-
- if (SDL_CurrentContext != data->context) {
- /* We'll update the clip rect after we rebind the context */
- return 0;
- }
-
- if (renderer->clipping_enabled) {
- const SDL_Rect *rect = &renderer->clip_rect;
- data->glEnable(GL_SCISSOR_TEST);
- if (renderer->target) {
- data->glScissor(renderer->viewport.x + rect->x, renderer->viewport.y + rect->y, rect->w, rect->h);
- } else {
- int w, h;
-
- SDL_GL_GetDrawableSize(renderer->window, &w, &h);
- data->glScissor(renderer->viewport.x + rect->x, h - renderer->viewport.y - rect->y - rect->h, rect->w, rect->h);
- }
- } else {
- data->glDisable(GL_SCISSOR_TEST);
- }
- return 0;
-}
-
-static void
-GLES_SetColor(GLES_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
-
- if (color != data->current.color) {
- data->glColor4f((GLfloat) r * inv255f,
- (GLfloat) g * inv255f,
- (GLfloat) b * inv255f,
- (GLfloat) a * inv255f);
- data->current.color = color;
- }
-}
-
-static void
-GLES_SetBlendMode(GLES_RenderData * data, SDL_BlendMode blendMode)
-{
- if (blendMode != data->current.blendMode) {
- if (blendMode == SDL_BLENDMODE_NONE) {
- data->glDisable(GL_BLEND);
- } else {
- data->glEnable(GL_BLEND);
- if (data->GL_OES_blend_func_separate_supported) {
- data->glBlendFuncSeparateOES(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blendMode)),
- GetBlendFunc(SDL_GetBlendModeDstColorFactor(blendMode)),
- GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blendMode)),
- GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blendMode)));
- } else {
- data->glBlendFunc(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blendMode)),
- GetBlendFunc(SDL_GetBlendModeDstColorFactor(blendMode)));
- }
- if (data->GL_OES_blend_equation_separate_supported) {
- data->glBlendEquationSeparateOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blendMode)),
- GetBlendEquation(SDL_GetBlendModeAlphaOperation(blendMode)));
- } else if (data->GL_OES_blend_subtract_supported) {
- data->glBlendEquationOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blendMode)));
- }
- }
- data->current.blendMode = blendMode;
- }
-}
-
-static void
-GLES_SetTexCoords(GLES_RenderData * data, SDL_bool enabled)
-{
- if (enabled != data->current.tex_coords) {
- if (enabled) {
- data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- } else {
- data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- data->current.tex_coords = enabled;
- }
-}
-
-static void
-GLES_SetDrawingState(SDL_Renderer * renderer)
-{
- GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-
- GLES_ActivateRenderer(renderer);
-
- GLES_SetColor(data, (GLfloat) renderer->r,
- (GLfloat) renderer->g,
- (GLfloat) renderer->b,
- (GLfloat) renderer->a);
-
- GLES_SetBlendMode(data, renderer->blendMode);
-
- GLES_SetTexCoords(data, SDL_FALSE);
-}
-
-static int
-GLES_RenderClear(SDL_Renderer * renderer)
-{
- GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-
- GLES_ActivateRenderer(renderer);
-
- data->glClearColor((GLfloat) renderer->r * inv255f,
- (GLfloat) renderer->g * inv255f,
- (GLfloat) renderer->b * inv255f,
- (GLfloat) renderer->a * inv255f);
-
- if (renderer->clipping_enabled) {
- data->glDisable(GL_SCISSOR_TEST);
- }
-
- data->glClear(GL_COLOR_BUFFER_BIT);
-
- if (renderer->clipping_enabled) {
- data->glEnable(GL_SCISSOR_TEST);
- }
-
- return 0;
-}
-
-static int
-GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
- int count)
-{
- GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
- GLfloat *vertices;
- int idx;
-
- GLES_SetDrawingState(renderer);
-
- /* Emit the specified vertices as points */
- vertices = SDL_stack_alloc(GLfloat, count * 2);
- for (idx = 0; idx < count; ++idx) {
- GLfloat x = points[idx].x + 0.5f;
- GLfloat y = points[idx].y + 0.5f;
-
- vertices[idx * 2] = x;
- vertices[(idx * 2) + 1] = y;
- }
-
- data->glVertexPointer(2, GL_FLOAT, 0, vertices);
- data->glDrawArrays(GL_POINTS, 0, count);
- SDL_stack_free(vertices);
- return 0;
-}
-
-static int
-GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
- int count)
-{
- GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
- GLfloat *vertices;
- int idx;
-
- GLES_SetDrawingState(renderer);
-
- /* Emit a line strip including the specified vertices */
- vertices = SDL_stack_alloc(GLfloat, count * 2);
- for (idx = 0; idx < count; ++idx) {
- GLfloat x = points[idx].x + 0.5f;
- GLfloat y = points[idx].y + 0.5f;
-
- vertices[idx * 2] = x;
- vertices[(idx * 2) + 1] = y;
- }
-
- data->glVertexPointer(2, GL_FLOAT, 0, vertices);
- if (count > 2 &&
- points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
- /* GL_LINE_LOOP takes care of the final segment */
- --count;
- data->glDrawArrays(GL_LINE_LOOP, 0, count);
- } else {
- data->glDrawArrays(GL_LINE_STRIP, 0, count);
- /* We need to close the endpoint of the line */
- data->glDrawArrays(GL_POINTS, count-1, 1);
- }
- SDL_stack_free(vertices);
-
- return 0;
-}
-
-static int
-GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects,
- int count)
-{
- GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+ GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (GLfloat), 0, &cmd->data.draw.first);
int i;
- GLES_SetDrawingState(renderer);
+ if (!verts) {
+ return -1;
+ }
- for (i = 0; i < count; ++i) {
- const SDL_FRect *rect = &rects[i];
- GLfloat minx = rect->x;
- GLfloat maxx = rect->x + rect->w;
- GLfloat miny = rect->y;
- GLfloat maxy = rect->y + rect->h;
- GLfloat vertices[8];
- vertices[0] = minx;
- vertices[1] = miny;
- vertices[2] = maxx;
- vertices[3] = miny;
- vertices[4] = minx;
- vertices[5] = maxy;
- vertices[6] = maxx;
- vertices[7] = maxy;
-
- data->glVertexPointer(2, GL_FLOAT, 0, vertices);
- data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ cmd->data.draw.count = count;
+ for (i = 0; i < count; i++) {
+ *(verts++) = 0.5f + points[i].x;
+ *(verts++) = 0.5f + points[i].y;
}
return 0;
}
static int
-GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
- const SDL_Rect * srcrect, const SDL_FRect * dstrect)
+GLES_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
{
- GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+ GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 8 * sizeof (GLfloat), 0, &cmd->data.draw.first);
+ int i;
+
+ if (!verts) {
+ return -1;
+ }
+
+ cmd->data.draw.count = count;
+
+ for (i = 0; i < count; i++) {
+ const SDL_FRect *rect = &rects[i];
+ const GLfloat minx = rect->x;
+ const GLfloat maxx = rect->x + rect->w;
+ const GLfloat miny = rect->y;
+ const GLfloat maxy = rect->y + rect->h;
+ *(verts++) = minx;
+ *(verts++) = miny;
+ *(verts++) = maxx;
+ *(verts++) = miny;
+ *(verts++) = minx;
+ *(verts++) = maxy;
+ *(verts++) = maxx;
+ *(verts++) = maxy;
+ }
+
+ return 0;
+}
+
+static int
+GLES_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
+ const SDL_Rect * srcrect, const SDL_FRect * dstrect)
+{
GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
GLfloat minx, miny, maxx, maxy;
GLfloat minu, maxu, minv, maxv;
- GLfloat vertices[8];
- GLfloat texCoords[8];
+ GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 16 * sizeof (GLfloat), 0, &cmd->data.draw.first);
- GLES_ActivateRenderer(renderer);
-
- data->glEnable(GL_TEXTURE_2D);
-
- data->glBindTexture(texturedata->type, texturedata->texture);
-
- if (texture->modMode) {
- GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a);
- } else {
- GLES_SetColor(data, 255, 255, 255, 255);
+ if (!verts) {
+ return -1;
}
- GLES_SetBlendMode(data, texture->blendMode);
-
- GLES_SetTexCoords(data, SDL_TRUE);
+ cmd->data.draw.count = 1;
minx = dstrect->x;
miny = dstrect->y;
@@ -1027,126 +621,351 @@
maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
maxv *= texturedata->texh;
- vertices[0] = minx;
- vertices[1] = miny;
- vertices[2] = maxx;
- vertices[3] = miny;
- vertices[4] = minx;
- vertices[5] = maxy;
- vertices[6] = maxx;
- vertices[7] = maxy;
+ *(verts++) = minx;
+ *(verts++) = miny;
+ *(verts++) = maxx;
+ *(verts++) = miny;
+ *(verts++) = minx;
+ *(verts++) = maxy;
+ *(verts++) = maxx;
+ *(verts++) = maxy;
- texCoords[0] = minu;
- texCoords[1] = minv;
- texCoords[2] = maxu;
- texCoords[3] = minv;
- texCoords[4] = minu;
- texCoords[5] = maxv;
- texCoords[6] = maxu;
- texCoords[7] = maxv;
-
- data->glVertexPointer(2, GL_FLOAT, 0, vertices);
- data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
- data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- data->glDisable(GL_TEXTURE_2D);
+ *(verts++) = minu;
+ *(verts++) = minv;
+ *(verts++) = maxu;
+ *(verts++) = minv;
+ *(verts++) = minu;
+ *(verts++) = maxv;
+ *(verts++) = maxu;
+ *(verts++) = maxv;
return 0;
}
static int
-GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
- const SDL_Rect * srcrect, const SDL_FRect * dstrect,
- const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
+GLES_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)
{
-
- GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
GLfloat minx, miny, maxx, maxy;
- GLfloat minu, maxu, minv, maxv;
GLfloat centerx, centery;
- GLfloat vertices[8];
- GLfloat texCoords[8];
+ GLfloat minu, maxu, minv, maxv;
+ GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 19 * sizeof (GLfloat), 0, &cmd->data.draw.first);
-
- GLES_ActivateRenderer(renderer);
-
- data->glEnable(GL_TEXTURE_2D);
-
- data->glBindTexture(texturedata->type, texturedata->texture);
-
- if (texture->modMode) {
- GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a);
- } else {
- GLES_SetColor(data, 255, 255, 255, 255);
+ if (!verts) {
+ return -1;
}
-
- GLES_SetBlendMode(data, texture->blendMode);
-
- GLES_SetTexCoords(data, SDL_TRUE);
centerx = center->x;
centery = center->y;
- /* Rotate and translate */
- data->glPushMatrix();
- data->glTranslatef(dstrect->x + centerx, dstrect->y + centery, 0.0f);
- data->glRotatef((GLfloat)angle, 0.0f, 0.0f, 1.0f);
-
if (flip & SDL_FLIP_HORIZONTAL) {
minx = dstrect->w - centerx;
maxx = -centerx;
- } else {
+ }
+ else {
minx = -centerx;
- maxx = dstrect->w - centerx;
+ maxx = dstrect->w - centerx;
}
if (flip & SDL_FLIP_VERTICAL) {
- miny = dstrect->h - centery;
+ miny = dstrect->h - centery;
maxy = -centery;
- } else {
+ }
+ else {
miny = -centery;
- maxy = dstrect->h - centery;
+ maxy = dstrect->h - centery;
}
- minu = (GLfloat) srcrect->x / texture->w;
+ minu = (GLfloat) srcquad->x / texture->w;
minu *= texturedata->texw;
- maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
+ maxu = (GLfloat) (srcquad->x + srcquad->w) / texture->w;
maxu *= texturedata->texw;
- minv = (GLfloat) srcrect->y / texture->h;
+ minv = (GLfloat) srcquad->y / texture->h;
minv *= texturedata->texh;
- maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
+ maxv = (GLfloat) (srcquad->y + srcquad->h) / texture->h;
maxv *= texturedata->texh;
- vertices[0] = minx;
- vertices[1] = miny;
- vertices[2] = maxx;
- vertices[3] = miny;
- vertices[4] = minx;
- vertices[5] = maxy;
- vertices[6] = maxx;
- vertices[7] = maxy;
+ cmd->data.draw.count = 1;
- texCoords[0] = minu;
- texCoords[1] = minv;
- texCoords[2] = maxu;
- texCoords[3] = minv;
- texCoords[4] = minu;
- texCoords[5] = maxv;
- texCoords[6] = maxu;
- texCoords[7] = maxv;
- data->glVertexPointer(2, GL_FLOAT, 0, vertices);
- data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
- data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- data->glPopMatrix();
- data->glDisable(GL_TEXTURE_2D);
+ *(verts++) = minx;
+ *(verts++) = miny;
+ *(verts++) = maxx;
+ *(verts++) = miny;
+ *(verts++) = minx;
+ *(verts++) = maxy;
+ *(verts++) = maxx;
+ *(verts++) = maxy;
+
+ *(verts++) = minu;
+ *(verts++) = minv;
+ *(verts++) = maxu;
+ *(verts++) = minv;
+ *(verts++) = minu;
+ *(verts++) = maxv;
+ *(verts++) = maxu;
+ *(verts++) = maxv;
+
+ *(verts++) = (GLfloat) dstrect->x + centerx;
+ *(verts++) = (GLfloat) dstrect->y + centery;
+ *(verts++) = (GLfloat) angle;
+
+ return 0;
+}
+
+static void
+SetDrawState(GLES_RenderData *data, const SDL_RenderCommand *cmd)
+{
+ const SDL_BlendMode blend = cmd->data.draw.blend;
+ const Uint8 r = cmd->data.draw.r;
+ const Uint8 g = cmd->data.draw.g;
+ const Uint8 b = cmd->data.draw.b;
+ const Uint8 a = cmd->data.draw.a;
+ const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
+
+ if (color != data->drawstate.color) {
+ const GLfloat fr = ((GLfloat) r) * inv255f;
+ const GLfloat fg = ((GLfloat) g) * inv255f;
+ const GLfloat fb = ((GLfloat) b) * inv255f;
+ const GLfloat fa = ((GLfloat) a) * inv255f;
+ data->glColor4f(fr, fg, fb, fa);
+ data->drawstate.color = color;
+ }
+
+ if (data->drawstate.viewport_dirty) {
+ const SDL_Rect *viewport = &data->drawstate.viewport;
+ const SDL_bool istarget = (data->drawstate.target != NULL);
+ data->glMatrixMode(GL_PROJECTION);
+ data->glLoadIdentity();
+ data->glViewport(viewport->x,
+ istarget ? viewport->y : (data->drawstate.drawableh - viewport->y - viewport->h),
+ viewport->w, viewport->h);
+ if (viewport->w && viewport->h) {
+ data->glOrthof((GLfloat) 0, (GLfloat) viewport->w,
+ (GLfloat) (istarget ? 0 : viewport->h),
+ (GLfloat) (istarget ? viewport->h : 0),
+ 0.0, 1.0);
+ }
+ data->glMatrixMode(GL_MODELVIEW);
+ data->drawstate.viewport_dirty = SDL_FALSE;
+ }
+
+ if (data->drawstate.cliprect_enabled_dirty) {
+ if (data->drawstate.cliprect_enabled) {
+ data->glEnable(GL_SCISSOR_TEST);
+ } else {
+ data->glDisable(GL_SCISSOR_TEST);
+ }
+ data->drawstate.cliprect_enabled_dirty = SDL_FALSE;
+ }
+
+ if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
+ const SDL_Rect *viewport = &data->drawstate.viewport;
+ const SDL_Rect *rect = &data->drawstate.cliprect;
+ const SDL_bool istarget = (data->drawstate.target != NULL);
+ data->glScissor(viewport->x + rect->x,
+ istarget ? viewport->y + rect->y : data->drawstate.drawableh - viewport->y - rect->y - rect->h,
+ rect->w, rect->h);
+ data->drawstate.cliprect_dirty = SDL_FALSE;
+ }
+
+ if (blend != data->drawstate.blend) {
+ if (blend == SDL_BLENDMODE_NONE) {
+ data->glDisable(GL_BLEND);
+ } else {
+ data->glEnable(GL_BLEND);
+ if (data->GL_OES_blend_func_separate_supported) {
+ data->glBlendFuncSeparateOES(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)),
+ GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)),
+ GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)),
+ GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend)));
+ } else {
+ data->glBlendFunc(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)),
+ GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)));
+ }
+ if (data->GL_OES_blend_equation_separate_supported) {
+ data->glBlendEquationSeparateOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blend)),
+ GetBlendEquation(SDL_GetBlendModeAlphaOperation(blend)));
+ } else if (data->GL_OES_blend_subtract_supported) {
+ data->glBlendEquationOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blend)));
+ }
+ }
+ data->drawstate.blend = blend;
+ }
+
+ if ((cmd->data.draw.texture != NULL) != data->drawstate.texturing) {
+ if (cmd->data.draw.texture == NULL) {
+ data->glDisable(GL_TEXTURE_2D);
+ data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ data->drawstate.texturing = SDL_FALSE;
+ } else {
+ data->glEnable(GL_TEXTURE_2D);
+ data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ data->drawstate.texturing = SDL_TRUE;
+ }
+ }
+}
+
+static void
+SetCopyState(GLES_RenderData *data, const SDL_RenderCommand *cmd)
+{
+ SDL_Texture *texture = cmd->data.draw.texture;
+ SetDrawState(data, cmd);
+
+ if (texture != data->drawstate.texture) {
+ GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
+ data->glBindTexture(GL_TEXTURE_2D, texturedata->texture);
+ data->drawstate.texture = texture;
+ }
+}
+
+static int
+GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
+{
+ GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+ size_t i;
+
+ if (GLES_ActivateRenderer(renderer) < 0) {
+ return -1;
+ }
+
+ data->drawstate.target = renderer->target;
+
+ if (!renderer->target) {
+ SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh);
+ }
+
+ while (cmd) {
+ switch (cmd->command) {
+ case SDL_RENDERCMD_SETDRAWCOLOR: {
+ break; /* not used in this render backend. */
+ }
+
+ case SDL_RENDERCMD_SETVIEWPORT: {
+ SDL_Rect *viewport = &data->drawstate.viewport;
+ if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
+ SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
+ data->drawstate.viewport_dirty = SDL_TRUE;
+ }
+ break;
+ }
+
+ case SDL_RENDERCMD_SETCLIPRECT: {
+ const SDL_Rect *rect = &cmd->data.cliprect.rect;
+ if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
+ data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
+ data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
+ }
+ if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
+ SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
+ data->drawstate.cliprect_dirty = SDL_TRUE;
+ }
+ break;
+ }
+
+ case SDL_RENDERCMD_CLEAR: {
+ const Uint8 r = cmd->data.color.r;
+ const Uint8 g = cmd->data.color.g;
+ const Uint8 b = cmd->data.color.b;
+ const Uint8 a = cmd->data.color.a;
+ const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
+ if (color != data->drawstate.clear_color) {
+ const GLfloat fr = ((GLfloat) r) * inv255f;
+ const GLfloat fg = ((GLfloat) g) * inv255f;
+ const GLfloat fb = ((GLfloat) b) * inv255f;
+ const GLfloat fa = ((GLfloat) a) * inv255f;
+ data->glClearColor(fr, fg, fb, fa);
+ data->drawstate.clear_color = color;
+ }
+
+ if (data->drawstate.cliprect_enabled || data->drawstate.cliprect_enabled_dirty) {
+ data->glDisable(GL_SCISSOR_TEST);
+ data->drawstate.cliprect_enabled_dirty = data->drawstate.cliprect_enabled;
+ }
+
+ data->glClear(GL_COLOR_BUFFER_BIT);
+
+ break;
+ }
+
+ case SDL_RENDERCMD_DRAW_POINTS: {
+ const size_t count = cmd->data.draw.count;
+ const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
+ SetDrawState(data, cmd);
+ data->glVertexPointer(2, GL_FLOAT, 0, verts);
+ data->glDrawArrays(GL_POINTS, 0, (GLsizei) count);
+ break;
+ }
+
+ case SDL_RENDERCMD_DRAW_LINES: {
+ const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
+ const size_t count = cmd->data.draw.count;
+ SetDrawState(data, cmd);
+ data->glVertexPointer(2, GL_FLOAT, 0, verts);
+ if (count > 2 && (verts[0] == verts[(count-1)*2]) && (verts[1] == verts[(count*2)-1])) {
+ /* GL_LINE_LOOP takes care of the final segment */
+ data->glDrawArrays(GL_LINE_LOOP, 0, (GLsizei) (count - 1));
+ } else {
+ data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) count);
+ /* We need to close the endpoint of the line */
+ data->glDrawArrays(GL_POINTS, (GLsizei) (count - 1), 1);
+ }
+ break;
+ }
+
+ case SDL_RENDERCMD_FILL_RECTS: {
+ const size_t count = cmd->data.draw.count;
+ const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
+ GLsizei offset = 0;
+ SetDrawState(data, cmd);
+ data->glVertexPointer(2, GL_FLOAT, 0, verts);
+ for (i = 0; i < count; ++i, offset += 4) {
+ data->glDrawArrays(GL_TRIANGLE_STRIP, offset, 4);
+ }
+ break;
+ }
+
+ case SDL_RENDERCMD_COPY: {
+ const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
+ SetCopyState(data, cmd);
+ data->glVertexPointer(2, GL_FLOAT, 0, verts);
+ data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8);
+ data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ break;
+ }
+
+ case SDL_RENDERCMD_COPY_EX: {
+ const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
+ const GLfloat translatex = verts[16];
+ const GLfloat translatey = verts[17];
+ const GLfloat angle = verts[18];
+ SetCopyState(data, cmd);
+ data->glVertexPointer(2, GL_FLOAT, 0, verts);
+ data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8);
+
+ /* Translate to flip, rotate, translate to position */
+ data->glPushMatrix();
+ data->glTranslatef(translatex, translatey, 0.0f);
+ data->glRotatef(angle, 0.0, 0.0, 1.0);
+ data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ data->glPopMatrix();
+ break;
+ }
+
+ case SDL_RENDERCMD_NO_OP:
+ break;
+ }
+
+ cmd = cmd->next;
+ }
return 0;
}
static int
GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
- Uint32 pixel_format, void * pixels, int pitch)
+ Uint32 pixel_format, void * pixels, int pitch)
{
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888;
@@ -1173,10 +992,11 @@
/* Flip the rows to be top-down if necessary */
if (!renderer->target) {
+ SDL_bool isstack;
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
dst = (Uint8*)temp_pixels;
- tmp = SDL_stack_alloc(Uint8, length);
+ tmp = SDL_small_alloc(Uint8, length, &isstack);
rows = rect->h / 2;
while (rows--) {
SDL_memcpy(tmp, dst, length);
@@ -1185,7 +1005,7 @@
dst += temp_pitch;
src -= temp_pitch;
}
- SDL_stack_free(tmp);
+ SDL_small_free(tmp, isstack);
}
status = SDL_ConvertPixels(rect->w, rect->h,
@@ -1212,6 +1032,13 @@
GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
GLES_ActivateRenderer(renderer);
+
+ if (renderdata->drawstate.texture == texture) {
+ renderdata->drawstate.texture = NULL;
+ }
+ if (renderdata->drawstate.target == texture) {
+ renderdata->drawstate.target = NULL;
+ }
if (!data) {
return;
@@ -1253,6 +1080,9 @@
data->glEnable(GL_TEXTURE_2D);
data->glBindTexture(texturedata->type, texturedata->texture);
+ data->drawstate.texture = texture;
+ data->drawstate.texturing = SDL_TRUE;
+
if (texw) {
*texw = (float)texturedata->texw;
}
@@ -1270,9 +1100,174 @@
GLES_ActivateRenderer(renderer);
data->glDisable(texturedata->type);
+ data->drawstate.texture = NULL;
+ data->drawstate.texturing = SDL_FALSE;
+
return 0;
}
+static SDL_Renderer *
+GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
+{
+ SDL_Renderer *renderer;
+ GLES_RenderData *data;
+ GLint value;
+ Uint32 window_flags;
+ int profile_mask = 0, major = 0, minor = 0;
+ SDL_bool changed_window = SDL_FALSE;
+
+ SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_mask);
+ SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
+ SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
+
+ window_flags = SDL_GetWindowFlags(window);
+ if (!(window_flags & SDL_WINDOW_OPENGL) ||
+ profile_mask != SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
+
+ changed_window = SDL_TRUE;
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, RENDERER_CONTEXT_MAJOR);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, RENDERER_CONTEXT_MINOR);
+
+ if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
+ goto error;
+ }
+ }
+
+ renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
+ if (!renderer) {
+ SDL_OutOfMemory();
+ goto error;
+ }
+
+ data = (GLES_RenderData *) SDL_calloc(1, sizeof(*data));
+ if (!data) {
+ GLES_DestroyRenderer(renderer);
+ SDL_OutOfMemory();
+ goto error;
+ }
+
+ renderer->WindowEvent = GLES_WindowEvent;
+ renderer->GetOutputSize = GLES_GetOutputSize;
+ renderer->SupportsBlendMode = GLES_SupportsBlendMode;
+ renderer->CreateTexture = GLES_CreateTexture;
+ renderer->UpdateTexture = GLES_UpdateTexture;
+ renderer->LockTexture = GLES_LockTexture;
+ renderer->UnlockTexture = GLES_UnlockTexture;
+ renderer->SetTextureScaleMode = GLES_SetTextureScaleMode;
+ renderer->SetRenderTarget = GLES_SetRenderTarget;
+ renderer->QueueSetViewport = GLES_QueueSetViewport;
+ renderer->QueueSetDrawColor = GLES_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
+ renderer->QueueDrawPoints = GLES_QueueDrawPoints;
+ renderer->QueueDrawLines = GLES_QueueDrawPoints; /* lines and points queue vertices the same way. */
+ renderer->QueueFillRects = GLES_QueueFillRects;
+ renderer->QueueCopy = GLES_QueueCopy;
+ renderer->QueueCopyEx = GLES_QueueCopyEx;
+ renderer->RunCommandQueue = GLES_RunCommandQueue;
+ renderer->RenderReadPixels = GLES_RenderReadPixels;
+ renderer->RenderPresent = GLES_RenderPresent;
+ renderer->DestroyTexture = GLES_DestroyTexture;
+ renderer->DestroyRenderer = GLES_DestroyRenderer;
+ renderer->GL_BindTexture = GLES_BindTexture;
+ renderer->GL_UnbindTexture = GLES_UnbindTexture;
+ renderer->info = GLES_RenderDriver.info;
+ renderer->info.flags = SDL_RENDERER_ACCELERATED;
+ renderer->driverdata = data;
+ renderer->window = window;
+
+ data->context = SDL_GL_CreateContext(window);
+ if (!data->context) {
+ GLES_DestroyRenderer(renderer);
+ goto error;
+ }
+ if (SDL_GL_MakeCurrent(window, data->context) < 0) {
+ GLES_DestroyRenderer(renderer);
+ goto error;
+ }
+
+ if (GLES_LoadFunctions(data) < 0) {
+ GLES_DestroyRenderer(renderer);
+ goto error;
+ }
+
+ if (flags & SDL_RENDERER_PRESENTVSYNC) {
+ SDL_GL_SetSwapInterval(1);
+ } else {
+ SDL_GL_SetSwapInterval(0);
+ }
+ if (SDL_GL_GetSwapInterval() > 0) {
+ renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
+ }
+
+ value = 0;
+ data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
+ renderer->info.max_texture_width = value;
+ value = 0;
+ data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
+ renderer->info.max_texture_height = value;
+
+ /* Android does not report GL_OES_framebuffer_object but the functionality seems to be there anyway */
+ if (SDL_GL_ExtensionSupported("GL_OES_framebuffer_object") || data->glGenFramebuffersOES) {
+ data->GL_OES_framebuffer_object_supported = SDL_TRUE;
+ renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
+
+ value = 0;
+ data->glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &value);
+ data->window_framebuffer = (GLuint)value;
+ }
+ data->framebuffers = NULL;
+
+ if (SDL_GL_ExtensionSupported("GL_OES_blend_func_separate")) {
+ data->GL_OES_blend_func_separate_supported = SDL_TRUE;
+ }
+ if (SDL_GL_ExtensionSupported("GL_OES_blend_equation_separate")) {
+ data->GL_OES_blend_equation_separate_supported = SDL_TRUE;
+ }
+ if (SDL_GL_ExtensionSupported("GL_OES_blend_subtract")) {
+ data->GL_OES_blend_subtract_supported = SDL_TRUE;
+ }
+
+ /* Set up parameters for rendering */
+ data->glDisable(GL_DEPTH_TEST);
+ data->glDisable(GL_CULL_FACE);
+
+ data->glMatrixMode(GL_MODELVIEW);
+ data->glLoadIdentity();
+
+ data->glEnableClientState(GL_VERTEX_ARRAY);
+ data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+
+ data->drawstate.blend = SDL_BLENDMODE_INVALID;
+ data->drawstate.color = 0xFFFFFFFF;
+ data->drawstate.clear_color = 0xFFFFFFFF;
+
+ return renderer;
+
+error:
+ if (changed_window) {
+ /* Uh oh, better try to put it back... */
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile_mask);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
+ SDL_RecreateWindow(window, window_flags);
+ }
+ return NULL;
+}
+
+SDL_RenderDriver GLES_RenderDriver = {
+ GLES_CreateRenderer,
+ {
+ "opengles",
+ (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),
+ 1,
+ {SDL_PIXELFORMAT_ABGR8888},
+ 0,
+ 0
+ }
+};
+
#endif /* SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */
--
Gitblit v1.9.3