mirror of https://github.com/encounter/SDL.git
opengles2: Use client-side arrays on everything but Emscripten.
Turns out they're much faster! Fixes #5206.
This commit is contained in:
parent
bb9ebad74b
commit
f9b918ff40
|
@ -28,6 +28,16 @@
|
|||
#include "../../video/SDL_blit.h"
|
||||
#include "SDL_shaders_gles2.h"
|
||||
|
||||
/* WebGL doesn't offer client-side arrays, so use Vertex Buffer Objects
|
||||
on Emscripten, which converts GLES2 into WebGL calls.
|
||||
In all other cases, attempt to use client-side arrays, as they tend to
|
||||
be faster. */
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#define USE_VERTEX_BUFFER_OBJECTS 1
|
||||
#else
|
||||
#define USE_VERTEX_BUFFER_OBJECTS 0
|
||||
#endif
|
||||
|
||||
/* To prevent unnecessary window recreation,
|
||||
* these should match the defaults selected in SDL_GL_ResetAttributes
|
||||
*/
|
||||
|
@ -151,9 +161,12 @@ typedef struct GLES2_RenderData
|
|||
GLES2_ProgramCache program_cache;
|
||||
Uint8 clear_r, clear_g, clear_b, clear_a;
|
||||
|
||||
#if USE_VERTEX_BUFFER_OBJECTS
|
||||
GLuint vertex_buffers[8];
|
||||
size_t vertex_buffer_size[8];
|
||||
int current_vertex_buffer;
|
||||
#endif
|
||||
|
||||
GLES2_DrawStateCache drawstate;
|
||||
} GLES2_RenderData;
|
||||
|
||||
|
@ -844,7 +857,7 @@ GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture
|
|||
}
|
||||
|
||||
static int
|
||||
SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_ImageSource imgsrc)
|
||||
SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_ImageSource imgsrc, void *vertices)
|
||||
{
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
const SDL_BlendMode blend = cmd->data.draw.blend;
|
||||
|
@ -926,7 +939,7 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
|
|||
}
|
||||
|
||||
if (texture) {
|
||||
SDL_Vertex *verts = (SDL_Vertex *) (cmd->data.draw.first);
|
||||
SDL_Vertex *verts = (SDL_Vertex *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *)&verts->tex_coord);
|
||||
}
|
||||
|
||||
|
@ -960,7 +973,7 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
|
|||
|
||||
/* all drawing commands use this */
|
||||
{
|
||||
SDL_VertexSolid *verts = (SDL_VertexSolid *) (cmd->data.draw.first);
|
||||
SDL_VertexSolid *verts = (SDL_VertexSolid *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) &verts->position);
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE /* Normalized */, stride, (const GLvoid *) &verts->color);
|
||||
}
|
||||
|
@ -969,7 +982,7 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
|
|||
}
|
||||
|
||||
static int
|
||||
SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertices)
|
||||
{
|
||||
GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata;
|
||||
GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
|
||||
|
@ -1079,7 +1092,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
|||
}
|
||||
}
|
||||
|
||||
return SetDrawState(data, cmd, sourceType);
|
||||
return SetDrawState(data, cmd, sourceType, vertices);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1087,8 +1100,11 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
|||
{
|
||||
GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata;
|
||||
const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
|
||||
|
||||
#if USE_VERTEX_BUFFER_OBJECTS
|
||||
const int vboidx = data->current_vertex_buffer;
|
||||
const GLuint vbo = data->vertex_buffers[vboidx];
|
||||
#endif
|
||||
|
||||
if (GLES2_ActivateRenderer(renderer) < 0) {
|
||||
return -1;
|
||||
|
@ -1106,6 +1122,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
|||
}
|
||||
}
|
||||
|
||||
#if USE_VERTEX_BUFFER_OBJECTS
|
||||
/* upload the new VBO data for this set of commands. */
|
||||
data->glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
if (data->vertex_buffer_size[vboidx] < vertsize) {
|
||||
|
@ -1120,6 +1137,8 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
|||
if (data->current_vertex_buffer >= SDL_arraysize(data->vertex_buffers)) {
|
||||
data->current_vertex_buffer = 0;
|
||||
}
|
||||
vertices = NULL; /* attrib pointers will be offsets into the VBO. */
|
||||
#endif
|
||||
|
||||
while (cmd) {
|
||||
switch (cmd->command) {
|
||||
|
@ -1184,7 +1203,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
|||
break;
|
||||
|
||||
case SDL_RENDERCMD_DRAW_LINES: {
|
||||
if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) {
|
||||
if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID, vertices) == 0) {
|
||||
size_t count = cmd->data.draw.count;
|
||||
if (count > 2) {
|
||||
/* joined lines cannot be grouped */
|
||||
|
@ -1242,9 +1261,9 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
|||
}
|
||||
|
||||
if (thistexture) {
|
||||
ret = SetCopyState(renderer, cmd);
|
||||
ret = SetCopyState(renderer, cmd, vertices);
|
||||
} else {
|
||||
ret = SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID);
|
||||
ret = SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID, vertices);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
|
@ -1308,8 +1327,10 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer)
|
|||
data->framebuffers = nextnode;
|
||||
}
|
||||
|
||||
#if USE_VERTEX_BUFFER_OBJECTS
|
||||
data->glDeleteBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers);
|
||||
GL_CheckError("", renderer);
|
||||
#endif
|
||||
|
||||
SDL_GL_DeleteContext(data->context);
|
||||
}
|
||||
|
@ -2071,8 +2092,10 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
|
|||
data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
|
||||
renderer->info.max_texture_height = value;
|
||||
|
||||
#if USE_VERTEX_BUFFER_OBJECTS
|
||||
/* we keep a few of these and cycle through them, so data can live for a few frames. */
|
||||
data->glGenBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers);
|
||||
#endif
|
||||
|
||||
data->framebuffers = NULL;
|
||||
data->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer);
|
||||
|
|
Loading…
Reference in New Issue