Skip to content

Commit 52ea295

Browse files
committed
Use GL_BGRA_EXT with OpenGL ES 2 where available
1 parent 419245d commit 52ea295

1 file changed

Lines changed: 87 additions & 27 deletions

File tree

src/render/opengles2/SDL_render_gles2.c

Lines changed: 87 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ typedef struct GLES2_RenderData
189189

190190
bool GL_OES_EGL_image_external_supported;
191191
bool GL_EXT_blend_minmax_supported;
192+
bool GL_EXT_texture_format_BGRA8888_supported;
192193

193194
#define SDL_PROC(ret, func, params) ret (APIENTRY *func) params;
194195
#include "SDL_gles2funcs.h"
@@ -301,6 +302,14 @@ static bool GLES2_LoadFunctions(GLES2_RenderData *data)
301302
return true;
302303
}
303304

305+
static bool GLES2_NeedColorSwap(SDL_Texture *target)
306+
{
307+
GLES2_TextureData *tdata = target ? (GLES2_TextureData *)target->internal : NULL;
308+
if (tdata && tdata->pixel_format == GL_BGRA_EXT)
309+
return false;
310+
return (target && (target->format == SDL_PIXELFORMAT_BGRA32 || target->format == SDL_PIXELFORMAT_BGRX32));
311+
}
312+
304313
static GLES2_FBOList *GLES2_GetFBO(GLES2_RenderData *data, Uint32 w, Uint32 h)
305314
{
306315
GLES2_FBOList *result = data->framebuffers;
@@ -633,7 +642,7 @@ static bool GLES2_SelectProgram(GLES2_RenderData *data, SDL_Texture *texture, GL
633642
GLES2_ShaderType vtype, ftype;
634643
GLES2_ProgramCacheEntry *program;
635644
GLES2_TextureData *tdata = texture ? (GLES2_TextureData *)texture->internal : NULL;
636-
const bool colorswap = (data->drawstate.target && (data->drawstate.target->format == SDL_PIXELFORMAT_BGRA32 || data->drawstate.target->format == SDL_PIXELFORMAT_BGRX32));
645+
const bool colorswap = GLES2_NeedColorSwap(data->drawstate.target);
637646
const float *shader_params = NULL;
638647
int shader_params_len = 0;
639648

@@ -849,7 +858,7 @@ static bool GLES2_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
849858

850859
static bool GLES2_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
851860
{
852-
const bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_BGRA32 || renderer->target->format == SDL_PIXELFORMAT_BGRX32));
861+
const bool colorswap = GLES2_NeedColorSwap(renderer->target);
853862
SDL_VertexSolid *verts = (SDL_VertexSolid *)SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first);
854863
int i;
855864
SDL_FColor color = cmd->data.draw.color;
@@ -882,7 +891,7 @@ static bool GLES2_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd
882891

883892
static bool GLES2_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
884893
{
885-
const bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_BGRA32 || renderer->target->format == SDL_PIXELFORMAT_BGRX32));
894+
const bool colorswap = GLES2_NeedColorSwap(renderer->target);
886895
int i;
887896
GLfloat prevx, prevy;
888897
SDL_VertexSolid *verts = (SDL_VertexSolid *)SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first);
@@ -943,7 +952,7 @@ static bool GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
943952
float scale_x, float scale_y)
944953
{
945954
int i;
946-
const bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_BGRA32 || renderer->target->format == SDL_PIXELFORMAT_BGRX32));
955+
const bool colorswap = GLES2_NeedColorSwap(renderer->target);
947956
int count = indices ? num_indices : num_vertices;
948957
const float color_scale = cmd->data.draw.color_scale;
949958

@@ -1220,8 +1229,11 @@ static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, v
12201229
case SDL_PIXELFORMAT_RGB565:
12211230
case SDL_PIXELFORMAT_RGBA5551:
12221231
case SDL_PIXELFORMAT_RGBA4444:
1223-
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1224-
break;
1232+
if (GLES2_NeedColorSwap(texture)) {
1233+
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1234+
break;
1235+
}
1236+
// fall through
12251237
case SDL_PIXELFORMAT_BGRX32:
12261238
sourceType = GLES2_IMAGESOURCE_TEXTURE;
12271239
break;
@@ -1236,8 +1248,11 @@ static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, v
12361248
switch (renderer->target->format) {
12371249
case SDL_PIXELFORMAT_BGRA32:
12381250
case SDL_PIXELFORMAT_BGRX32:
1239-
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1240-
break;
1251+
if (GLES2_NeedColorSwap(renderer->target)) {
1252+
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1253+
break;
1254+
}
1255+
// fall through
12411256
case SDL_PIXELFORMAT_RGBX32:
12421257
sourceType = GLES2_IMAGESOURCE_TEXTURE;
12431258
break;
@@ -1251,33 +1266,47 @@ static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, v
12511266
case SDL_PIXELFORMAT_RGB565:
12521267
case SDL_PIXELFORMAT_RGBA5551:
12531268
case SDL_PIXELFORMAT_RGBA4444:
1254-
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1255-
break;
1269+
if (GLES2_NeedColorSwap(texture)) {
1270+
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1271+
break;
1272+
}
1273+
// fall through
12561274
case SDL_PIXELFORMAT_BGRA32:
12571275
sourceType = GLES2_IMAGESOURCE_TEXTURE_OPAQUE;
12581276
break;
12591277
case SDL_PIXELFORMAT_RGBX32:
1260-
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1261-
break;
1278+
if (GLES2_NeedColorSwap(texture)) {
1279+
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1280+
break;
1281+
}
1282+
// fall through
12621283
default:
1284+
sourceType = GLES2_IMAGESOURCE_TEXTURE;
12631285
break;
12641286
}
12651287
break;
12661288
case SDL_PIXELFORMAT_RGBX32:
12671289
switch (renderer->target->format) {
1290+
case SDL_PIXELFORMAT_BGRA32:
1291+
if (GLES2_NeedColorSwap(renderer->target)) {
1292+
sourceType = GLES2_IMAGESOURCE_TEXTURE_OPAQUE_COLORSWAP;
1293+
break;
1294+
}
1295+
// fall through
12681296
case SDL_PIXELFORMAT_RGBA32:
12691297
case SDL_PIXELFORMAT_RGB565:
12701298
case SDL_PIXELFORMAT_RGBA5551:
12711299
case SDL_PIXELFORMAT_RGBA4444:
12721300
sourceType = GLES2_IMAGESOURCE_TEXTURE_OPAQUE;
12731301
break;
1274-
case SDL_PIXELFORMAT_BGRA32:
1275-
sourceType = GLES2_IMAGESOURCE_TEXTURE_OPAQUE_COLORSWAP;
1276-
break;
12771302
case SDL_PIXELFORMAT_BGRX32:
1278-
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1279-
break;
1303+
if (GLES2_NeedColorSwap(renderer->target)) {
1304+
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1305+
break;
1306+
}
1307+
// fall through
12801308
default:
1309+
sourceType = GLES2_IMAGESOURCE_TEXTURE;
12811310
break;
12821311
}
12831312
break;
@@ -1308,17 +1337,23 @@ static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, v
13081337
sourceType = GLES2_IMAGESOURCE_TEXTURE_INDEX8;
13091338
break;
13101339
case SDL_PIXELFORMAT_BGRA32:
1311-
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1312-
break;
1340+
if (tdata->pixel_format != GL_BGRA_EXT) {
1341+
sourceType = GLES2_IMAGESOURCE_TEXTURE_COLORSWAP;
1342+
break;
1343+
}
1344+
// fall through
13131345
case SDL_PIXELFORMAT_RGBA32:
13141346
case SDL_PIXELFORMAT_RGB565:
13151347
case SDL_PIXELFORMAT_RGBA5551:
13161348
case SDL_PIXELFORMAT_RGBA4444:
13171349
sourceType = GLES2_IMAGESOURCE_TEXTURE;
13181350
break;
13191351
case SDL_PIXELFORMAT_BGRX32:
1320-
sourceType = GLES2_IMAGESOURCE_TEXTURE_OPAQUE_COLORSWAP;
1321-
break;
1352+
if (tdata->pixel_format != GL_BGRA_EXT) {
1353+
sourceType = GLES2_IMAGESOURCE_TEXTURE_OPAQUE_COLORSWAP;
1354+
break;
1355+
}
1356+
// fall through
13221357
case SDL_PIXELFORMAT_RGBX32:
13231358
sourceType = GLES2_IMAGESOURCE_TEXTURE_OPAQUE;
13241359
break;
@@ -1462,7 +1497,7 @@ static void GLES2_InvalidateCachedState(SDL_Renderer *renderer)
14621497
static bool GLES2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
14631498
{
14641499
GLES2_RenderData *data = (GLES2_RenderData *)renderer->internal;
1465-
const bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_BGRA32 || renderer->target->format == SDL_PIXELFORMAT_BGRX32));
1500+
const bool colorswap = GLES2_NeedColorSwap(renderer->target);
14661501

14671502
#if USE_VERTEX_BUFFER_OBJECTS
14681503
const int vboidx = data->current_vertex_buffer;
@@ -1785,8 +1820,14 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
17851820
// Determine the corresponding GLES texture format params
17861821
switch (texture->format) {
17871822
case SDL_PIXELFORMAT_BGRA32:
1788-
case SDL_PIXELFORMAT_RGBA32:
17891823
case SDL_PIXELFORMAT_BGRX32:
1824+
if (renderdata->GL_EXT_texture_format_BGRA8888_supported) {
1825+
format = GL_BGRA_EXT;
1826+
type = GL_UNSIGNED_BYTE;
1827+
break;
1828+
}
1829+
// fall through
1830+
case SDL_PIXELFORMAT_RGBA32:
17901831
case SDL_PIXELFORMAT_RGBX32:
17911832
format = GL_RGBA;
17921833
type = GL_UNSIGNED_BYTE;
@@ -2291,13 +2332,18 @@ static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
22912332
static SDL_Surface *GLES2_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
22922333
{
22932334
GLES2_RenderData *data = (GLES2_RenderData *)renderer->internal;
2335+
/* GLES only supports RGBA32 or an implementation-defined format */
22942336
SDL_PixelFormat format = SDL_PIXELFORMAT_RGBA32;
22952337
SDL_Surface *surface;
22962338

22972339
if (renderer->target) {
22982340
switch (renderer->target->format) {
22992341
case SDL_PIXELFORMAT_BGRA32:
23002342
case SDL_PIXELFORMAT_BGRX32:
2343+
if (GLES2_NeedColorSwap(renderer->target)) {
2344+
format = renderer->target->format;
2345+
}
2346+
break;
23012347
case SDL_PIXELFORMAT_RGBX32:
23022348
format = renderer->target->format;
23032349
break;
@@ -2476,10 +2522,24 @@ static bool GLES2_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL
24762522
data->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer);
24772523
data->window_framebuffer = (GLuint)window_framebuffer;
24782524

2479-
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGRA32); // SDL_PIXELFORMAT_ARGB8888 on little endian systems
2480-
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA32);
2481-
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGRX32);
2482-
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBX32);
2525+
if (SDL_GL_ExtensionSupported("GL_EXT_texture_format_BGRA8888")) {
2526+
data->GL_EXT_texture_format_BGRA8888_supported = true;
2527+
}
2528+
2529+
if (data->GL_EXT_texture_format_BGRA8888_supported) {
2530+
// Assume that BGRA32 is the best format when supported
2531+
// TODO: Is there a better way of determining this?
2532+
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGRA32); // SDL_PIXELFORMAT_ARGB8888 on little endian systems
2533+
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGRX32);
2534+
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA32);
2535+
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBX32);
2536+
} else {
2537+
// BGRA32 is emulated using shaders - treat RGBA32 as the best format
2538+
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA32);
2539+
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBX32);
2540+
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGRA32); // SDL_PIXELFORMAT_ARGB8888 on little endian systems
2541+
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGRX32);
2542+
}
24832543
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGB565);
24842544
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA5551);
24852545
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA4444);

0 commit comments

Comments
 (0)