diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 972f11f17..1c60d4e5d 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 0a2b1a7d5..886b8eda1 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_TextureNV12BT709[] = \ +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_SHADER_BODY \ + NV12_RA_SHADER_BODY \ +; +static const Uint8 GLES2_Fragment_TextureNV12BT709_RG[] = \ + YUV_SHADER_PROLOGUE \ + BT709_SHADER_CONSTANTS \ + 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 5565d4aae..a03a980fe 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,