From c55ab9631f38583092b9e609f4441fc4bdb11ca9 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 13 Nov 2021 22:21:57 -0800
Subject: [PATCH] Added a hint for alternate OpenGL NV12 data format
---
src/render/opengles2/SDL_render_gles2.c | 12 ++++-
src/render/opengles2/SDL_shaders_gles2.c | 62 ++++++++++++++++++------
src/render/opengles2/SDL_shaders_gles2.h | 6 ++-
3 files changed, 62 insertions(+), 18 deletions(-)
diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c
index 972f11f17a..1c60d4e5dc 100644
--- a/src/render/opengles2/SDL_render_gles2.c
+++ b/src/render/opengles2/SDL_render_gles2.c
@@ -569,10 +569,18 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG;
break;
case SDL_YUV_CONVERSION_BT601:
- ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601;
+ if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) {
+ ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601;
+ } else {
+ ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601;
+ }
break;
case SDL_YUV_CONVERSION_BT709:
- ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709;
+ if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) {
+ ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709;
+ } else {
+ ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709;
+ }
break;
default:
SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h));
diff --git a/src/render/opengles2/SDL_shaders_gles2.c b/src/render/opengles2/SDL_shaders_gles2.c
index 0a2b1a7d59..886b8eda12 100644
--- a/src/render/opengles2/SDL_shaders_gles2.c
+++ b/src/render/opengles2/SDL_shaders_gles2.c
@@ -154,7 +154,7 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
"uniform sampler2D u_texture;\n" \
"uniform sampler2D u_texture_u;\n" \
"uniform sampler2D u_texture_v;\n" \
-"varying vec4 v_color;\n" \
+"varying vec4 v_color;\n" \
"varying vec2 v_texCoord;\n" \
"\n" \
@@ -176,10 +176,10 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
"\n" \
" // That was easy. :) \n" \
" gl_FragColor = vec4(rgb, 1);\n" \
-" gl_FragColor *= v_color;\n" \
+" gl_FragColor *= v_color;\n" \
"}" \
-#define NV12_SHADER_BODY \
+#define NV12_RA_SHADER_BODY \
"\n" \
"void main()\n" \
"{\n" \
@@ -196,7 +196,27 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
"\n" \
" // That was easy. :) \n" \
" gl_FragColor = vec4(rgb, 1);\n" \
-" gl_FragColor *= v_color;\n" \
+" gl_FragColor *= v_color;\n" \
+"}" \
+
+#define NV12_RG_SHADER_BODY \
+"\n" \
+"void main()\n" \
+"{\n" \
+" mediump vec3 yuv;\n" \
+" lowp vec3 rgb;\n" \
+"\n" \
+" // Get the YUV values \n" \
+" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \
+" yuv.yz = texture2D(u_texture_u, v_texCoord).rg;\n" \
+"\n" \
+" // Do the color transform \n" \
+" yuv += offset;\n" \
+" rgb = matrix * yuv;\n" \
+"\n" \
+" // That was easy. :) \n" \
+" gl_FragColor = vec4(rgb, 1);\n" \
+" gl_FragColor *= v_color;\n" \
"}" \
#define NV21_SHADER_BODY \
@@ -216,7 +236,7 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
"\n" \
" // That was easy. :) \n" \
" gl_FragColor = vec4(rgb, 1);\n" \
-" gl_FragColor *= v_color;\n" \
+" gl_FragColor *= v_color;\n" \
"}" \
/* YUV to ABGR conversion */
@@ -240,17 +260,27 @@ static const Uint8 GLES2_Fragment_TextureYUVBT709[] = \
static const Uint8 GLES2_Fragment_TextureNV12JPEG[] = \
YUV_SHADER_PROLOGUE \
JPEG_SHADER_CONSTANTS \
- NV12_SHADER_BODY \
+ NV12_RA_SHADER_BODY \
;
-static const Uint8 GLES2_Fragment_TextureNV12BT601[] = \
+static const Uint8 GLES2_Fragment_TextureNV12BT601_RA[] = \
YUV_SHADER_PROLOGUE \
BT601_SHADER_CONSTANTS \
- NV12_SHADER_BODY \
+ NV12_RA_SHADER_BODY \
+;
+static const Uint8 GLES2_Fragment_TextureNV12BT601_RG[] = \
+ YUV_SHADER_PROLOGUE \
+ BT601_SHADER_CONSTANTS \
+ NV12_RG_SHADER_BODY \
+;
+static const Uint8 GLES2_Fragment_TextureNV12BT709_RA[] = \
+ YUV_SHADER_PROLOGUE \
+ BT709_SHADER_CONSTANTS \
+ NV12_RA_SHADER_BODY \
;
-static const Uint8 GLES2_Fragment_TextureNV12BT709[] = \
+static const Uint8 GLES2_Fragment_TextureNV12BT709_RG[] = \
YUV_SHADER_PROLOGUE \
BT709_SHADER_CONSTANTS \
- NV12_SHADER_BODY \
+ NV12_RG_SHADER_BODY \
;
/* NV21 to ABGR conversion */
@@ -313,10 +343,14 @@ const Uint8 *GLES2_GetShader(GLES2_ShaderType type)
return GLES2_Fragment_TextureYUVBT709;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG:
return GLES2_Fragment_TextureNV12JPEG;
- case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601:
- return GLES2_Fragment_TextureNV12BT601;
- case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709:
- return GLES2_Fragment_TextureNV12BT709;
+ case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601:
+ return GLES2_Fragment_TextureNV12BT601_RA;
+ case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601:
+ return GLES2_Fragment_TextureNV12BT601_RG;
+ case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709:
+ return GLES2_Fragment_TextureNV12BT709_RA;
+ case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709:
+ return GLES2_Fragment_TextureNV12BT709_RG;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG:
return GLES2_Fragment_TextureNV21JPEG;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601:
diff --git a/src/render/opengles2/SDL_shaders_gles2.h b/src/render/opengles2/SDL_shaders_gles2.h
index 5565d4aae5..a03a980fec 100644
--- a/src/render/opengles2/SDL_shaders_gles2.h
+++ b/src/render/opengles2/SDL_shaders_gles2.h
@@ -38,8 +38,10 @@ typedef enum
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709,
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG,
- GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601,
- GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709,
+ GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601,
+ GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601,
+ GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709,
+ GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709,