[libcamera-devel,6/7] qcam: viewfinder_gl: Merge the semi-planar UV and VU shaders

Message ID 20200916145254.1644-7-laurent.pinchart@ideasonboard.com
State Accepted
Commit ae9e7fbf3a8bf45b08951b650aec3f91997fafc3
Headers show
Series
  • qcam: Accelerate packed YUV rendering with OpenGL
Related show

Commit Message

Laurent Pinchart Sept. 16, 2020, 2:52 p.m. UTC
Use macros to select the U and V pattern, to avoid code duplication
between the two semi-planar shaders.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 ...YUV_2_planes_UV.frag => YUV_2_planes.frag} |  9 +++++-
 src/qcam/assets/shader/YUV_2_planes_VU.frag   | 32 -------------------
 src/qcam/assets/shader/shaders.qrc            |  3 +-
 src/qcam/viewfinder_gl.cpp                    | 18 +++++++----
 4 files changed, 21 insertions(+), 41 deletions(-)
 rename src/qcam/assets/shader/{YUV_2_planes_UV.frag => YUV_2_planes.frag} (68%)
 delete mode 100644 src/qcam/assets/shader/YUV_2_planes_VU.frag

Comments

Niklas Söderlund Sept. 16, 2020, 3:25 p.m. UTC | #1
Hi Laurent,

Thanks for your patch.

On 2020-09-16 17:52:53 +0300, Laurent Pinchart wrote:
> Use macros to select the U and V pattern, to avoid code duplication
> between the two semi-planar shaders.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

This is really neat!

Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>

> ---
>  ...YUV_2_planes_UV.frag => YUV_2_planes.frag} |  9 +++++-
>  src/qcam/assets/shader/YUV_2_planes_VU.frag   | 32 -------------------
>  src/qcam/assets/shader/shaders.qrc            |  3 +-
>  src/qcam/viewfinder_gl.cpp                    | 18 +++++++----
>  4 files changed, 21 insertions(+), 41 deletions(-)
>  rename src/qcam/assets/shader/{YUV_2_planes_UV.frag => YUV_2_planes.frag} (68%)
>  delete mode 100644 src/qcam/assets/shader/YUV_2_planes_VU.frag
> 
> diff --git a/src/qcam/assets/shader/YUV_2_planes_UV.frag b/src/qcam/assets/shader/YUV_2_planes.frag
> similarity index 68%
> rename from src/qcam/assets/shader/YUV_2_planes_UV.frag
> rename to src/qcam/assets/shader/YUV_2_planes.frag
> index 081caea9214b..125f1c850a33 100644
> --- a/src/qcam/assets/shader/YUV_2_planes_UV.frag
> +++ b/src/qcam/assets/shader/YUV_2_planes.frag
> @@ -2,7 +2,7 @@
>  /*
>   * Copyright (C) 2020, Linaro
>   *
> - * YUV_2_planes_UV.frag - Fragment shader code for NV12, NV16 and NV24 formats
> + * YUV_2_planes.frag - Fragment shader code for NV12, NV16 and NV24 formats
>   */
>  
>  #ifdef GL_ES
> @@ -24,8 +24,15 @@ void main(void)
>  	);
>  
>  	yuv.x = texture2D(tex_y, textureOut).r - 0.063;
> +#if defined(YUV_PATTERN_UV)
>  	yuv.y = texture2D(tex_u, textureOut).r - 0.500;
>  	yuv.z = texture2D(tex_u, textureOut).g - 0.500;
> +#elif defined(YUV_PATTERN_VU)
> +	yuv.y = texture2D(tex_u, textureOut).g - 0.500;
> +	yuv.z = texture2D(tex_u, textureOut).r - 0.500;
> +#else
> +#error Invalid pattern
> +#endif
>  
>  	rgb = yuv2rgb_bt601_mat * yuv;
>  	gl_FragColor = vec4(rgb, 1.0);
> diff --git a/src/qcam/assets/shader/YUV_2_planes_VU.frag b/src/qcam/assets/shader/YUV_2_planes_VU.frag
> deleted file mode 100644
> index f4a5a5ac46c0..000000000000
> --- a/src/qcam/assets/shader/YUV_2_planes_VU.frag
> +++ /dev/null
> @@ -1,32 +0,0 @@
> -/* SPDX-License-Identifier: LGPL-2.1-or-later */
> -/*
> - * Copyright (C) 2020, Linaro
> - *
> - * YUV_2_planes_VU.frag - Fragment shader code for NV21, NV61 and NV42 formats
> - */
> -
> -#ifdef GL_ES
> -precision mediump float;
> -#endif
> -
> -varying vec2 textureOut;
> -uniform sampler2D tex_y;
> -uniform sampler2D tex_u;
> -
> -void main(void)
> -{
> -	vec3 yuv;
> -	vec3 rgb;
> -	mat3 yuv2rgb_bt601_mat = mat3(
> -		vec3(1.164,  1.164, 1.164),
> -		vec3(0.000, -0.392, 2.017),
> -		vec3(1.596, -0.813, 0.000)
> -	);
> -
> -	yuv.x = texture2D(tex_y, textureOut).r - 0.063;
> -	yuv.y = texture2D(tex_u, textureOut).g - 0.500;
> -	yuv.z = texture2D(tex_u, textureOut).r - 0.500;
> -
> -	rgb = yuv2rgb_bt601_mat * yuv;
> -	gl_FragColor = vec4(rgb, 1.0);
> -}
> diff --git a/src/qcam/assets/shader/shaders.qrc b/src/qcam/assets/shader/shaders.qrc
> index 533396d1fb28..7010d8433c9b 100644
> --- a/src/qcam/assets/shader/shaders.qrc
> +++ b/src/qcam/assets/shader/shaders.qrc
> @@ -2,8 +2,7 @@
>  <!DOCTYPE RCC><RCC version="1.0">
>  <qresource>
>  	<file>YUV.vert</file>
> -	<file>YUV_2_planes_UV.frag</file>
> -	<file>YUV_2_planes_VU.frag</file>
> +	<file>YUV_2_planes.frag</file>
>  	<file>YUV_3_planes.frag</file>
>  </qresource>
>  </RCC>
> diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp
> index 7cb5fb63656f..b8a4827267c3 100644
> --- a/src/qcam/viewfinder_gl.cpp
> +++ b/src/qcam/viewfinder_gl.cpp
> @@ -106,32 +106,38 @@ bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format)
>  	case libcamera::formats::NV12:
>  		horzSubSample_ = 2;
>  		vertSubSample_ = 2;
> -		fragmentShaderFile_ = ":YUV_2_planes_UV.frag";
> +		fragmentShaderDefines_.append("#define YUV_PATTERN_UV");
> +		fragmentShaderFile_ = ":YUV_2_planes.frag";
>  		break;
>  	case libcamera::formats::NV21:
>  		horzSubSample_ = 2;
>  		vertSubSample_ = 2;
> -		fragmentShaderFile_ = ":YUV_2_planes_VU.frag";
> +		fragmentShaderDefines_.append("#define YUV_PATTERN_VU");
> +		fragmentShaderFile_ = ":YUV_2_planes.frag";
>  		break;
>  	case libcamera::formats::NV16:
>  		horzSubSample_ = 2;
>  		vertSubSample_ = 1;
> -		fragmentShaderFile_ = ":YUV_2_planes_UV.frag";
> +		fragmentShaderDefines_.append("#define YUV_PATTERN_UV");
> +		fragmentShaderFile_ = ":YUV_2_planes.frag";
>  		break;
>  	case libcamera::formats::NV61:
>  		horzSubSample_ = 2;
>  		vertSubSample_ = 1;
> -		fragmentShaderFile_ = ":YUV_2_planes_VU.frag";
> +		fragmentShaderDefines_.append("#define YUV_PATTERN_VU");
> +		fragmentShaderFile_ = ":YUV_2_planes.frag";
>  		break;
>  	case libcamera::formats::NV24:
>  		horzSubSample_ = 1;
>  		vertSubSample_ = 1;
> -		fragmentShaderFile_ = ":YUV_2_planes_UV.frag";
> +		fragmentShaderDefines_.append("#define YUV_PATTERN_UV");
> +		fragmentShaderFile_ = ":YUV_2_planes.frag";
>  		break;
>  	case libcamera::formats::NV42:
>  		horzSubSample_ = 1;
>  		vertSubSample_ = 1;
> -		fragmentShaderFile_ = ":YUV_2_planes_VU.frag";
> +		fragmentShaderDefines_.append("#define YUV_PATTERN_VU");
> +		fragmentShaderFile_ = ":YUV_2_planes.frag";
>  		break;
>  	case libcamera::formats::YUV420:
>  		horzSubSample_ = 2;
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

Patch

diff --git a/src/qcam/assets/shader/YUV_2_planes_UV.frag b/src/qcam/assets/shader/YUV_2_planes.frag
similarity index 68%
rename from src/qcam/assets/shader/YUV_2_planes_UV.frag
rename to src/qcam/assets/shader/YUV_2_planes.frag
index 081caea9214b..125f1c850a33 100644
--- a/src/qcam/assets/shader/YUV_2_planes_UV.frag
+++ b/src/qcam/assets/shader/YUV_2_planes.frag
@@ -2,7 +2,7 @@ 
 /*
  * Copyright (C) 2020, Linaro
  *
- * YUV_2_planes_UV.frag - Fragment shader code for NV12, NV16 and NV24 formats
+ * YUV_2_planes.frag - Fragment shader code for NV12, NV16 and NV24 formats
  */
 
 #ifdef GL_ES
@@ -24,8 +24,15 @@  void main(void)
 	);
 
 	yuv.x = texture2D(tex_y, textureOut).r - 0.063;
+#if defined(YUV_PATTERN_UV)
 	yuv.y = texture2D(tex_u, textureOut).r - 0.500;
 	yuv.z = texture2D(tex_u, textureOut).g - 0.500;
+#elif defined(YUV_PATTERN_VU)
+	yuv.y = texture2D(tex_u, textureOut).g - 0.500;
+	yuv.z = texture2D(tex_u, textureOut).r - 0.500;
+#else
+#error Invalid pattern
+#endif
 
 	rgb = yuv2rgb_bt601_mat * yuv;
 	gl_FragColor = vec4(rgb, 1.0);
diff --git a/src/qcam/assets/shader/YUV_2_planes_VU.frag b/src/qcam/assets/shader/YUV_2_planes_VU.frag
deleted file mode 100644
index f4a5a5ac46c0..000000000000
--- a/src/qcam/assets/shader/YUV_2_planes_VU.frag
+++ /dev/null
@@ -1,32 +0,0 @@ 
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2020, Linaro
- *
- * YUV_2_planes_VU.frag - Fragment shader code for NV21, NV61 and NV42 formats
- */
-
-#ifdef GL_ES
-precision mediump float;
-#endif
-
-varying vec2 textureOut;
-uniform sampler2D tex_y;
-uniform sampler2D tex_u;
-
-void main(void)
-{
-	vec3 yuv;
-	vec3 rgb;
-	mat3 yuv2rgb_bt601_mat = mat3(
-		vec3(1.164,  1.164, 1.164),
-		vec3(0.000, -0.392, 2.017),
-		vec3(1.596, -0.813, 0.000)
-	);
-
-	yuv.x = texture2D(tex_y, textureOut).r - 0.063;
-	yuv.y = texture2D(tex_u, textureOut).g - 0.500;
-	yuv.z = texture2D(tex_u, textureOut).r - 0.500;
-
-	rgb = yuv2rgb_bt601_mat * yuv;
-	gl_FragColor = vec4(rgb, 1.0);
-}
diff --git a/src/qcam/assets/shader/shaders.qrc b/src/qcam/assets/shader/shaders.qrc
index 533396d1fb28..7010d8433c9b 100644
--- a/src/qcam/assets/shader/shaders.qrc
+++ b/src/qcam/assets/shader/shaders.qrc
@@ -2,8 +2,7 @@ 
 <!DOCTYPE RCC><RCC version="1.0">
 <qresource>
 	<file>YUV.vert</file>
-	<file>YUV_2_planes_UV.frag</file>
-	<file>YUV_2_planes_VU.frag</file>
+	<file>YUV_2_planes.frag</file>
 	<file>YUV_3_planes.frag</file>
 </qresource>
 </RCC>
diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp
index 7cb5fb63656f..b8a4827267c3 100644
--- a/src/qcam/viewfinder_gl.cpp
+++ b/src/qcam/viewfinder_gl.cpp
@@ -106,32 +106,38 @@  bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format)
 	case libcamera::formats::NV12:
 		horzSubSample_ = 2;
 		vertSubSample_ = 2;
-		fragmentShaderFile_ = ":YUV_2_planes_UV.frag";
+		fragmentShaderDefines_.append("#define YUV_PATTERN_UV");
+		fragmentShaderFile_ = ":YUV_2_planes.frag";
 		break;
 	case libcamera::formats::NV21:
 		horzSubSample_ = 2;
 		vertSubSample_ = 2;
-		fragmentShaderFile_ = ":YUV_2_planes_VU.frag";
+		fragmentShaderDefines_.append("#define YUV_PATTERN_VU");
+		fragmentShaderFile_ = ":YUV_2_planes.frag";
 		break;
 	case libcamera::formats::NV16:
 		horzSubSample_ = 2;
 		vertSubSample_ = 1;
-		fragmentShaderFile_ = ":YUV_2_planes_UV.frag";
+		fragmentShaderDefines_.append("#define YUV_PATTERN_UV");
+		fragmentShaderFile_ = ":YUV_2_planes.frag";
 		break;
 	case libcamera::formats::NV61:
 		horzSubSample_ = 2;
 		vertSubSample_ = 1;
-		fragmentShaderFile_ = ":YUV_2_planes_VU.frag";
+		fragmentShaderDefines_.append("#define YUV_PATTERN_VU");
+		fragmentShaderFile_ = ":YUV_2_planes.frag";
 		break;
 	case libcamera::formats::NV24:
 		horzSubSample_ = 1;
 		vertSubSample_ = 1;
-		fragmentShaderFile_ = ":YUV_2_planes_UV.frag";
+		fragmentShaderDefines_.append("#define YUV_PATTERN_UV");
+		fragmentShaderFile_ = ":YUV_2_planes.frag";
 		break;
 	case libcamera::formats::NV42:
 		horzSubSample_ = 1;
 		vertSubSample_ = 1;
-		fragmentShaderFile_ = ":YUV_2_planes_VU.frag";
+		fragmentShaderDefines_.append("#define YUV_PATTERN_VU");
+		fragmentShaderFile_ = ":YUV_2_planes.frag";
 		break;
 	case libcamera::formats::YUV420:
 		horzSubSample_ = 2;