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 "../../video/SDL_blit.h"
|
||||||
#include "SDL_shaders_gles2.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,
|
/* To prevent unnecessary window recreation,
|
||||||
* these should match the defaults selected in SDL_GL_ResetAttributes
|
* these should match the defaults selected in SDL_GL_ResetAttributes
|
||||||
*/
|
*/
|
||||||
|
@ -151,9 +161,12 @@ typedef struct GLES2_RenderData
|
||||||
GLES2_ProgramCache program_cache;
|
GLES2_ProgramCache program_cache;
|
||||||
Uint8 clear_r, clear_g, clear_b, clear_a;
|
Uint8 clear_r, clear_g, clear_b, clear_a;
|
||||||
|
|
||||||
|
#if USE_VERTEX_BUFFER_OBJECTS
|
||||||
GLuint vertex_buffers[8];
|
GLuint vertex_buffers[8];
|
||||||
size_t vertex_buffer_size[8];
|
size_t vertex_buffer_size[8];
|
||||||
int current_vertex_buffer;
|
int current_vertex_buffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
GLES2_DrawStateCache drawstate;
|
GLES2_DrawStateCache drawstate;
|
||||||
} GLES2_RenderData;
|
} GLES2_RenderData;
|
||||||
|
|
||||||
|
@ -844,7 +857,7 @@ GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
SDL_Texture *texture = cmd->data.draw.texture;
|
||||||
const SDL_BlendMode blend = cmd->data.draw.blend;
|
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) {
|
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);
|
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 */
|
/* 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_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);
|
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
|
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_RenderData *data = (GLES2_RenderData *) renderer->driverdata;
|
||||||
GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
|
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
|
static int
|
||||||
|
@ -1087,8 +1100,11 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||||
{
|
{
|
||||||
GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata;
|
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));
|
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 int vboidx = data->current_vertex_buffer;
|
||||||
const GLuint vbo = data->vertex_buffers[vboidx];
|
const GLuint vbo = data->vertex_buffers[vboidx];
|
||||||
|
#endif
|
||||||
|
|
||||||
if (GLES2_ActivateRenderer(renderer) < 0) {
|
if (GLES2_ActivateRenderer(renderer) < 0) {
|
||||||
return -1;
|
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. */
|
/* upload the new VBO data for this set of commands. */
|
||||||
data->glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
data->glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
if (data->vertex_buffer_size[vboidx] < vertsize) {
|
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)) {
|
if (data->current_vertex_buffer >= SDL_arraysize(data->vertex_buffers)) {
|
||||||
data->current_vertex_buffer = 0;
|
data->current_vertex_buffer = 0;
|
||||||
}
|
}
|
||||||
|
vertices = NULL; /* attrib pointers will be offsets into the VBO. */
|
||||||
|
#endif
|
||||||
|
|
||||||
while (cmd) {
|
while (cmd) {
|
||||||
switch (cmd->command) {
|
switch (cmd->command) {
|
||||||
|
@ -1184,7 +1203,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_RENDERCMD_DRAW_LINES: {
|
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;
|
size_t count = cmd->data.draw.count;
|
||||||
if (count > 2) {
|
if (count > 2) {
|
||||||
/* joined lines cannot be grouped */
|
/* joined lines cannot be grouped */
|
||||||
|
@ -1242,9 +1261,9 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thistexture) {
|
if (thistexture) {
|
||||||
ret = SetCopyState(renderer, cmd);
|
ret = SetCopyState(renderer, cmd, vertices);
|
||||||
} else {
|
} else {
|
||||||
ret = SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID);
|
ret = SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID, vertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
@ -1308,8 +1327,10 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer)
|
||||||
data->framebuffers = nextnode;
|
data->framebuffers = nextnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_VERTEX_BUFFER_OBJECTS
|
||||||
data->glDeleteBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers);
|
data->glDeleteBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers);
|
||||||
GL_CheckError("", renderer);
|
GL_CheckError("", renderer);
|
||||||
|
#endif
|
||||||
|
|
||||||
SDL_GL_DeleteContext(data->context);
|
SDL_GL_DeleteContext(data->context);
|
||||||
}
|
}
|
||||||
|
@ -2071,8 +2092,10 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||||
data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
|
data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
|
||||||
renderer->info.max_texture_height = 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. */
|
/* 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);
|
data->glGenBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers);
|
||||||
|
#endif
|
||||||
|
|
||||||
data->framebuffers = NULL;
|
data->framebuffers = NULL;
|
||||||
data->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer);
|
data->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer);
|
||||||
|
|
Loading…
Reference in New Issue