render: Do state cache improvements for GLES1, too.

This commit is contained in:
Ryan C. Gordon 2018-09-25 21:35:09 -04:00
parent d04e55240e
commit 0d588cc4c9
1 changed files with 83 additions and 60 deletions

View File

@ -61,6 +61,18 @@ struct GLES_FBOList
GLES_FBOList *next; GLES_FBOList *next;
}; };
typedef struct
{
SDL_Rect viewport;
SDL_Texture *texture;
SDL_BlendMode blend;
SDL_bool cliprect_enabled;
SDL_Rect cliprect;
SDL_bool texturing;
Uint32 color;
Uint32 clear_color;
} GLES_DrawStateCache;
typedef struct typedef struct
{ {
SDL_GLContext context; SDL_GLContext context;
@ -77,6 +89,8 @@ typedef struct
SDL_bool GL_OES_blend_func_separate_supported; SDL_bool GL_OES_blend_func_separate_supported;
SDL_bool GL_OES_blend_equation_separate_supported; SDL_bool GL_OES_blend_equation_separate_supported;
SDL_bool GL_OES_blend_subtract_supported; SDL_bool GL_OES_blend_subtract_supported;
GLES_DrawStateCache drawstate;
} GLES_RenderData; } GLES_RenderData;
typedef struct typedef struct
@ -675,12 +689,11 @@ GLES_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture *
} }
static void static void
SetDrawState(const GLES_RenderData *data, const SDL_RenderCommand *cmd, SetDrawState(GLES_RenderData *data, const SDL_RenderCommand *cmd)
SDL_BlendMode *current_blend, SDL_bool *current_texturing)
{ {
const SDL_BlendMode blend = cmd->data.draw.blend; const SDL_BlendMode blend = cmd->data.draw.blend;
if (blend != *current_blend) { if (blend != data->drawstate.blend) {
if (blend == SDL_BLENDMODE_NONE) { if (blend == SDL_BLENDMODE_NONE) {
data->glDisable(GL_BLEND); data->glDisable(GL_BLEND);
} else { } else {
@ -701,34 +714,32 @@ SetDrawState(const GLES_RenderData *data, const SDL_RenderCommand *cmd,
data->glBlendEquationOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blend))); data->glBlendEquationOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blend)));
} }
} }
*current_blend = blend; data->drawstate.blend = blend;
} }
if ((cmd->data.draw.texture != NULL) != *current_texturing) { if ((cmd->data.draw.texture != NULL) != data->drawstate.texturing) {
if (cmd->data.draw.texture == NULL) { if (cmd->data.draw.texture == NULL) {
data->glDisable(GL_TEXTURE_2D); data->glDisable(GL_TEXTURE_2D);
data->glDisableClientState(GL_TEXTURE_COORD_ARRAY); data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
*current_texturing = SDL_FALSE; data->drawstate.texturing = SDL_FALSE;
} else { } else {
data->glEnable(GL_TEXTURE_2D); data->glEnable(GL_TEXTURE_2D);
data->glEnableClientState(GL_TEXTURE_COORD_ARRAY); data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
*current_texturing = SDL_FALSE; data->drawstate.texturing = SDL_TRUE;
} }
} }
} }
static void static void
SetCopyState(const GLES_RenderData *data, const SDL_RenderCommand *cmd, SetCopyState(const GLES_RenderData *data, const SDL_RenderCommand *cmd)
SDL_BlendMode *current_blend, SDL_bool *current_texturing,
SDL_Texture **current_texture)
{ {
SDL_Texture *texture = cmd->data.draw.texture; SDL_Texture *texture = cmd->data.draw.texture;
SetDrawState(data, cmd, current_blend, current_texturing); SetDrawState(data, cmd);
if (texture != *current_texture) { if (texture != data->drawstate.texture) {
GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
data->glBindTexture(GL_TEXTURE_2D, texturedata->texture); data->glBindTexture(GL_TEXTURE_2D, texturedata->texture);
*current_texture = texture; data->drawstate.texture = texture;
} }
} }
@ -736,13 +747,8 @@ static int
GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
{ {
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
SDL_Rect viewport;
SDL_Texture *bound_texture = NULL;
SDL_BlendMode blend = SDL_BLENDMODE_INVALID;
int drawablew = 0, drawableh = 0; int drawablew = 0, drawableh = 0;
SDL_bool cliprect_enabled = SDL_FALSE;
const SDL_bool istarget = renderer->target != NULL; const SDL_bool istarget = renderer->target != NULL;
SDL_bool texturing = SDL_FALSE;
size_t i; size_t i;
if (GLES_ActivateRenderer(renderer) < 0) { if (GLES_ActivateRenderer(renderer) < 0) {
@ -753,31 +759,37 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
SDL_GL_GetDrawableSize(renderer->window, &drawablew, &drawableh); SDL_GL_GetDrawableSize(renderer->window, &drawablew, &drawableh);
} }
data->glDisable(GL_TEXTURE_2D);
data->glMatrixMode(GL_MODELVIEW);
data->glLoadIdentity();
while (cmd) { while (cmd) {
switch (cmd->command) { switch (cmd->command) {
case SDL_RENDERCMD_SETDRAWCOLOR: { case SDL_RENDERCMD_SETDRAWCOLOR: {
data->glColor4f((GLfloat) cmd->data.color.r * inv255f, const Uint8 r = cmd->data.color.r;
(GLfloat) cmd->data.color.g * inv255f, const Uint8 g = cmd->data.color.g;
(GLfloat) cmd->data.color.b * inv255f, const Uint8 b = cmd->data.color.b;
(GLfloat) cmd->data.color.a * inv255f); const Uint8 a = cmd->data.color.a;
const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
if (color != data->drawstate.color) {
data->glColor4f((GLfloat) r * inv255f,
(GLfloat) g * inv255f,
(GLfloat) b * inv255f,
(GLfloat) a * inv255f);
data->drawstate.color = color;
}
break; break;
} }
case SDL_RENDERCMD_SETVIEWPORT: { case SDL_RENDERCMD_SETVIEWPORT: {
SDL_memcpy(&viewport, &cmd->data.viewport.rect, sizeof (viewport)); 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->glMatrixMode(GL_PROJECTION); data->glMatrixMode(GL_PROJECTION);
data->glLoadIdentity(); data->glLoadIdentity();
data->glViewport(viewport.x, data->glViewport(viewport->x,
istarget ? viewport.y : (drawableh - viewport.y - viewport.h), istarget ? viewport->y : (drawableh - viewport->y - viewport->h),
viewport.w, viewport.h); viewport->w, viewport->h);
if (viewport.w && viewport.h) { if (viewport->w && viewport->h) {
data->glOrthof((GLfloat) 0, (GLfloat) renderer->viewport.w, data->glOrthof((GLfloat) 0, (GLfloat) viewport->w,
(GLfloat) istarget ? 0 : renderer->viewport.h, (GLfloat) istarget ? 0 : viewport->h,
(GLfloat) istarget ? renderer->viewport.h : 0, (GLfloat) istarget ? viewport->h : 0,
0.0, 1.0); 0.0, 1.0);
} }
data->glMatrixMode(GL_MODELVIEW); data->glMatrixMode(GL_MODELVIEW);
@ -786,27 +798,38 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
case SDL_RENDERCMD_SETCLIPRECT: { case SDL_RENDERCMD_SETCLIPRECT: {
const SDL_Rect *rect = &cmd->data.cliprect.rect; const SDL_Rect *rect = &cmd->data.cliprect.rect;
cliprect_enabled = cmd->data.cliprect.enabled; if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
if (cliprect_enabled) { data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
data->glEnable(GL_SCISSOR_TEST); if (!data->drawstate.cliprect_enabled) {
} else {
data->glDisable(GL_SCISSOR_TEST); data->glDisable(GL_SCISSOR_TEST);
} } else {
const SDL_Rect *viewport = &data->drawstate.viewport;
if (cliprect_enabled) { data->glEnable(GL_SCISSOR_TEST);
data->glScissor(viewport.x + rect->x, if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
istarget ? viewport.y + rect->y : drawableh - viewport.y - rect->y - rect->h, data->glScissor(viewport->x + rect->x,
istarget ? viewport->y + rect->y : drawableh - viewport->y - rect->y - rect->h,
rect->w, rect->h); rect->w, rect->h);
SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
}
}
} }
break; break;
} }
case SDL_RENDERCMD_CLEAR: { case SDL_RENDERCMD_CLEAR: {
const GLfloat r = ((GLfloat) cmd->data.color.r) * inv255f; const Uint8 r = cmd->data.color.r;
const GLfloat g = ((GLfloat) cmd->data.color.g) * inv255f; const Uint8 g = cmd->data.color.g;
const GLfloat b = ((GLfloat) cmd->data.color.b) * inv255f; const Uint8 b = cmd->data.color.b;
const GLfloat a = ((GLfloat) cmd->data.color.a) * inv255f; const Uint8 a = cmd->data.color.a;
data->glClearColor(r, g, b, 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 (cliprect_enabled) { if (cliprect_enabled) {
data->glDisable(GL_SCISSOR_TEST); data->glDisable(GL_SCISSOR_TEST);
@ -823,7 +846,7 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
case SDL_RENDERCMD_DRAW_POINTS: { case SDL_RENDERCMD_DRAW_POINTS: {
const size_t count = cmd->data.draw.count; const size_t count = cmd->data.draw.count;
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
SetDrawState(data, cmd, &blend, &texturing); SetDrawState(data, cmd);
data->glVertexPointer(2, GL_FLOAT, 0, verts); data->glVertexPointer(2, GL_FLOAT, 0, verts);
data->glDrawArrays(GL_POINTS, 0, count); data->glDrawArrays(GL_POINTS, 0, count);
break; break;
@ -832,7 +855,7 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
case SDL_RENDERCMD_DRAW_LINES: { case SDL_RENDERCMD_DRAW_LINES: {
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
const size_t count = cmd->data.draw.count; const size_t count = cmd->data.draw.count;
SetDrawState(data, cmd, &blend, &texturing); SetDrawState(data, cmd);
data->glVertexPointer(2, GL_FLOAT, 0, verts); data->glVertexPointer(2, GL_FLOAT, 0, verts);
if (count > 2 && (verts[0] == verts[(count-1)*2]) && (verts[1] == verts[(count*2)-1])) { if (count > 2 && (verts[0] == verts[(count-1)*2]) && (verts[1] == verts[(count*2)-1])) {
/* GL_LINE_LOOP takes care of the final segment */ /* GL_LINE_LOOP takes care of the final segment */
@ -849,7 +872,7 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
const size_t count = cmd->data.draw.count; const size_t count = cmd->data.draw.count;
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
size_t offset = 0; size_t offset = 0;
SetDrawState(data, cmd, &blend, &texturing); SetDrawState(data, cmd);
data->glVertexPointer(2, GL_FLOAT, 0, verts); data->glVertexPointer(2, GL_FLOAT, 0, verts);
for (i = 0; i < count; ++i, offset += 4) { for (i = 0; i < count; ++i, offset += 4) {
data->glDrawArrays(GL_TRIANGLE_STRIP, offset, 4); data->glDrawArrays(GL_TRIANGLE_STRIP, offset, 4);
@ -859,7 +882,7 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
case SDL_RENDERCMD_COPY: { case SDL_RENDERCMD_COPY: {
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
SetCopyState(data, cmd, &blend, &texturing, &bound_texture); SetCopyState(data, cmd);
data->glVertexPointer(2, GL_FLOAT, 0, verts); data->glVertexPointer(2, GL_FLOAT, 0, verts);
data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8); data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8);
data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@ -871,7 +894,7 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
const GLfloat translatex = verts[16]; const GLfloat translatex = verts[16];
const GLfloat translatey = verts[17]; const GLfloat translatey = verts[17];
const GLfloat angle = verts[18]; const GLfloat angle = verts[18];
SetCopyState(data, cmd, &blend, &texturing, &bound_texture); SetCopyState(data, cmd);
data->glVertexPointer(2, GL_FLOAT, 0, verts); data->glVertexPointer(2, GL_FLOAT, 0, verts);
data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8); data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8);