Commit ee61cc31 authored by Sam Lantinga's avatar Sam Lantinga

Added OpenGL state caching for decent speed improvement.

parent 8c64c506
This diff is collapsed.
...@@ -60,7 +60,6 @@ struct GL_ShaderContext ...@@ -60,7 +60,6 @@ struct GL_ShaderContext
SDL_bool GL_ARB_texture_rectangle_supported; SDL_bool GL_ARB_texture_rectangle_supported;
GL_Shader current_shader;
GL_ShaderData shaders[NUM_SHADERS]; GL_ShaderData shaders[NUM_SHADERS];
}; };
...@@ -341,18 +340,7 @@ GL_CreateShaderContext() ...@@ -341,18 +340,7 @@ GL_CreateShaderContext()
void void
GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader) GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader)
{ {
/* Nothing to do if there's no shader support */
if (!ctx) {
return;
}
/* Nothing to do if there's no shader change */
if (shader == ctx->current_shader) {
return;
}
ctx->glUseProgramObjectARB(ctx->shaders[shader].program); ctx->glUseProgramObjectARB(ctx->shaders[shader].program);
ctx->current_shader = shader;
} }
void void
......
...@@ -84,7 +84,12 @@ SDL_RenderDriver GLES_RenderDriver = { ...@@ -84,7 +84,12 @@ SDL_RenderDriver GLES_RenderDriver = {
typedef struct typedef struct
{ {
SDL_GLContext context; SDL_GLContext context;
int blendMode; struct {
Uint32 color;
int blendMode;
GLenum scaleMode;
SDL_bool tex_coords;
} current;
SDL_bool useDrawTexture; SDL_bool useDrawTexture;
SDL_bool GL_OES_draw_texture_supported; SDL_bool GL_OES_draw_texture_supported;
...@@ -100,6 +105,7 @@ typedef struct ...@@ -100,6 +105,7 @@ typedef struct
GLenum formattype; GLenum formattype;
void *pixels; void *pixels;
int pitch; int pitch;
GLenum scaleMode;
} GLES_TextureData; } GLES_TextureData;
static void static void
...@@ -154,6 +160,33 @@ GLES_ActivateRenderer(SDL_Renderer * renderer) ...@@ -154,6 +160,33 @@ GLES_ActivateRenderer(SDL_Renderer * renderer)
return 0; 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 = 0;
data->current.blendMode = -1;
data->current.scaleMode = 0;
data->current.tex_coords = SDL_FALSE;
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
SDL_Renderer * SDL_Renderer *
GLES_CreateRenderer(SDL_Window * window, Uint32 flags) GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
{ {
...@@ -234,15 +267,8 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -234,15 +267,8 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.max_texture_height = value; renderer->info.max_texture_height = value;
/* Set up parameters for rendering */ /* Set up parameters for rendering */
data->blendMode = -1; GLES_ResetState(renderer);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnableClientState(GL_VERTEX_ARRAY);
//glEnableClientState(GL_TEXTURE_COORD_ARRAY);
return renderer; return renderer;
} }
...@@ -319,15 +345,10 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -319,15 +345,10 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
data->format = format; data->format = format;
data->formattype = type; data->formattype = type;
data->scaleMode = GL_LINEAR;
glBindTexture(data->type, data->texture); glBindTexture(data->type, data->texture);
glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
GL_LINEAR); glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
glTexImage2D(data->type, 0, internalFormat, texture_w, glTexImage2D(data->type, 0, internalFormat, texture_w,
texture_h, 0, format, type, NULL); texture_h, 0, format, type, NULL);
...@@ -453,25 +474,24 @@ GLES_UpdateViewport(SDL_Renderer * renderer) ...@@ -453,25 +474,24 @@ GLES_UpdateViewport(SDL_Renderer * renderer)
return 0; return 0;
} }
static int static void
GLES_RenderClear(SDL_Renderer * renderer) GLES_SetColor(GLES_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{ {
GLES_ActivateRenderer(renderer); Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
glClearColor((GLfloat) renderer->r * inv255f, if (color != data->current.color) {
(GLfloat) renderer->g * inv255f, glColor4f((GLfloat) r * inv255f,
(GLfloat) renderer->b * inv255f, (GLfloat) g * inv255f,
(GLfloat) renderer->a * inv255f); (GLfloat) b * inv255f,
(GLfloat) a * inv255f);
glClear(GL_COLOR_BUFFER_BIT); data->current.color = color;
}
return 0;
} }
static void static void
GLES_SetBlendMode(GLES_RenderData * data, int blendMode) GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
{ {
if (blendMode != data->blendMode) { if (blendMode != data->current.blendMode) {
switch (blendMode) { switch (blendMode) {
case SDL_BLENDMODE_NONE: case SDL_BLENDMODE_NONE:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
...@@ -493,10 +513,55 @@ GLES_SetBlendMode(GLES_RenderData * data, int blendMode) ...@@ -493,10 +513,55 @@ GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
glBlendFunc(GL_ZERO, GL_SRC_COLOR); glBlendFunc(GL_ZERO, GL_SRC_COLOR);
break; break;
} }
data->blendMode = blendMode; data->current.blendMode = blendMode;
}
}
static void
GLES_SetTexCoords(GLES_RenderData * data, SDL_bool enabled)
{
if (enabled != data->current.tex_coords) {
if (enabled) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
} else {
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_ActivateRenderer(renderer);
glClearColor((GLfloat) renderer->r * inv255f,
(GLfloat) renderer->g * inv255f,
(GLfloat) renderer->b * inv255f,
(GLfloat) renderer->a * inv255f);
glClear(GL_COLOR_BUFFER_BIT);
return 0;
}
static int static int
GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
int count) int count)
...@@ -505,14 +570,7 @@ GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, ...@@ -505,14 +570,7 @@ GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
int i; int i;
GLshort *vertices; GLshort *vertices;
GLES_ActivateRenderer(renderer); GLES_SetDrawingState(renderer);
GLES_SetBlendMode(data, renderer->blendMode);
glColor4f((GLfloat) renderer->r * inv255f,
(GLfloat) renderer->g * inv255f,
(GLfloat) renderer->b * inv255f,
(GLfloat) renderer->a * inv255f);
vertices = SDL_stack_alloc(GLshort, count*2); vertices = SDL_stack_alloc(GLshort, count*2);
for (i = 0; i < count; ++i) { for (i = 0; i < count; ++i) {
...@@ -534,14 +592,7 @@ GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, ...@@ -534,14 +592,7 @@ GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
int i; int i;
GLshort *vertices; GLshort *vertices;
GLES_ActivateRenderer(renderer); GLES_SetDrawingState(renderer);
GLES_SetBlendMode(data, renderer->blendMode);
glColor4f((GLfloat) renderer->r * inv255f,
(GLfloat) renderer->g * inv255f,
(GLfloat) renderer->b * inv255f,
(GLfloat) renderer->a * inv255f);
vertices = SDL_stack_alloc(GLshort, count*2); vertices = SDL_stack_alloc(GLshort, count*2);
for (i = 0; i < count; ++i) { for (i = 0; i < count; ++i) {
...@@ -569,14 +620,7 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, ...@@ -569,14 +620,7 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects,
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
int i; int i;
GLES_ActivateRenderer(renderer); GLES_SetDrawingState(renderer);
GLES_SetBlendMode(data, renderer->blendMode);
glColor4f((GLfloat) renderer->r * inv255f,
(GLfloat) renderer->g * inv255f,
(GLfloat) renderer->b * inv255f,
(GLfloat) renderer->a * inv255f);
for (i = 0; i < count; ++i) { for (i = 0; i < count; ++i) {
const SDL_Rect *rect = &rects[i]; const SDL_Rect *rect = &rects[i];
...@@ -614,21 +658,27 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -614,21 +658,27 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
GLES_ActivateRenderer(renderer); GLES_ActivateRenderer(renderer);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(texturedata->type, texturedata->texture); glBindTexture(texturedata->type, texturedata->texture);
if (texturedata->scaleMode != data->current.scaleMode) {
glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER,
texturedata->scaleMode);
glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER,
texturedata->scaleMode);
data->current.scaleMode = texturedata->scaleMode;
}
if (texture->modMode) { if (texture->modMode) {
glColor4f((GLfloat) texture->r * inv255f, GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a);
(GLfloat) texture->g * inv255f,
(GLfloat) texture->b * inv255f,
(GLfloat) texture->a * inv255f);
} else { } else {
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); GLES_SetColor(data, 255, 255, 255, 255);
} }
GLES_SetBlendMode(data, texture->blendMode); GLES_SetBlendMode(data, texture->blendMode);
GLES_SetTexCoords(data, SDL_TRUE);
if (data->GL_OES_draw_texture_supported && data->useDrawTexture) { if (data->GL_OES_draw_texture_supported && data->useDrawTexture) {
/* this code is a little funny because the viewport is upside down vs SDL's coordinate system */ /* this code is a little funny because the viewport is upside down vs SDL's coordinate system */
GLint cropRect[4]; GLint cropRect[4];
...@@ -685,8 +735,6 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -685,8 +735,6 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
return 0; return 0;
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment