[libcamera-devel] [PATCH 7/7] qcam: viewfinder_gl: Add support for RGB formats

Laurent Pinchart laurent.pinchart at ideasonboard.com
Tue Nov 3 16:50:25 CET 2020


Add support for 24-bit and 32-bit RGB formats. The fragment samples the
texture and reorders the components, using a pattern set through the
RGB_PATTERN macro.

An alternative to manual reordering in the shader would be to set the
texture swizzling mask. This is however not available in OpenGL ES
before version 3.0, which we don't mandate at the moment.

Only the BGR888 and RGB888 formats have been tested, with the vimc
pipeline handler.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/qcam/assets/shader/RGB.frag    | 22 +++++++++
 src/qcam/assets/shader/shaders.qrc |  1 +
 src/qcam/viewfinder_gl.cpp         | 71 ++++++++++++++++++++++++++++--
 3 files changed, 91 insertions(+), 3 deletions(-)
 create mode 100644 src/qcam/assets/shader/RGB.frag

diff --git a/src/qcam/assets/shader/RGB.frag b/src/qcam/assets/shader/RGB.frag
new file mode 100644
index 000000000000..4c374ac98095
--- /dev/null
+++ b/src/qcam/assets/shader/RGB.frag
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Laurent Pinchart
+ *
+ * RGB.frag - Fragment shader code for RGB formats
+ */
+
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+varying vec2 textureOut;
+uniform sampler2D tex_y;
+
+void main(void)
+{
+	vec3 rgb;
+
+	rgb = texture2D(tex_y, textureOut).RGB_PATTERN;
+
+	gl_FragColor = vec4(rgb, 1.0);
+}
diff --git a/src/qcam/assets/shader/shaders.qrc b/src/qcam/assets/shader/shaders.qrc
index 863109146281..8a8f9de1a5fa 100644
--- a/src/qcam/assets/shader/shaders.qrc
+++ b/src/qcam/assets/shader/shaders.qrc
@@ -1,6 +1,7 @@
 <!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
 <!DOCTYPE RCC><RCC version="1.0">
 <qresource>
+	<file>RGB.frag</file>
 	<file>YUV_2_planes.frag</file>
 	<file>YUV_3_planes.frag</file>
 	<file>YUV_packed.frag</file>
diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp
index cbc1365500f5..5d9b442e7985 100644
--- a/src/qcam/viewfinder_gl.cpp
+++ b/src/qcam/viewfinder_gl.cpp
@@ -14,21 +14,28 @@
 #include <libcamera/formats.h>
 
 static const QList<libcamera::PixelFormat> supportedFormats{
-	/* Packed (single plane) */
+	/* YUV - packed (single plane) */
 	libcamera::formats::UYVY,
 	libcamera::formats::VYUY,
 	libcamera::formats::YUYV,
 	libcamera::formats::YVYU,
-	/* Semi planar (two planes) */
+	/* YUV - semi planar (two planes) */
 	libcamera::formats::NV12,
 	libcamera::formats::NV21,
 	libcamera::formats::NV16,
 	libcamera::formats::NV61,
 	libcamera::formats::NV24,
 	libcamera::formats::NV42,
-	/* Fully planar (three planes) */
+	/* YUV - fully planar (three planes) */
 	libcamera::formats::YUV420,
 	libcamera::formats::YVU420,
+	/* RGB */
+	libcamera::formats::ABGR8888,
+	libcamera::formats::ARGB8888,
+	libcamera::formats::BGRA8888,
+	libcamera::formats::RGBA8888,
+	libcamera::formats::BGR888,
+	libcamera::formats::RGB888,
 };
 
 ViewFinderGL::ViewFinderGL(QWidget *parent)
@@ -172,6 +179,30 @@ bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format)
 		fragmentShaderDefines_.append("#define YUV_PATTERN_YVYU");
 		fragmentShaderFile_ = ":YUV_packed.frag";
 		break;
+	case libcamera::formats::ABGR8888:
+		fragmentShaderDefines_.append("#define RGB_PATTERN rgb");
+		fragmentShaderFile_ = ":RGB.frag";
+		break;
+	case libcamera::formats::ARGB8888:
+		fragmentShaderDefines_.append("#define RGB_PATTERN bgr");
+		fragmentShaderFile_ = ":RGB.frag";
+		break;
+	case libcamera::formats::BGRA8888:
+		fragmentShaderDefines_.append("#define RGB_PATTERN gba");
+		fragmentShaderFile_ = ":RGB.frag";
+		break;
+	case libcamera::formats::RGBA8888:
+		fragmentShaderDefines_.append("#define RGB_PATTERN abg");
+		fragmentShaderFile_ = ":RGB.frag";
+		break;
+	case libcamera::formats::BGR888:
+		fragmentShaderDefines_.append("#define RGB_PATTERN rgb");
+		fragmentShaderFile_ = ":RGB.frag";
+		break;
+	case libcamera::formats::RGB888:
+		fragmentShaderDefines_.append("#define RGB_PATTERN bgr");
+		fragmentShaderFile_ = ":RGB.frag";
+		break;
 	default:
 		ret = false;
 		qWarning() << "[ViewFinderGL]:"
@@ -481,6 +512,40 @@ void ViewFinderGL::doRender()
 					       1.0f / (size_.width() / 2 - 1));
 		break;
 
+	case libcamera::formats::ABGR8888:
+	case libcamera::formats::ARGB8888:
+	case libcamera::formats::BGRA8888:
+	case libcamera::formats::RGBA8888:
+		glActiveTexture(GL_TEXTURE0);
+		configureTexture(*textures_[0]);
+		glTexImage2D(GL_TEXTURE_2D,
+			     0,
+			     GL_RGBA,
+			     size_.width(),
+			     size_.height(),
+			     0,
+			     GL_RGBA,
+			     GL_UNSIGNED_BYTE,
+			     data_);
+		shaderProgram_.setUniformValue(textureUniformY_, 0);
+		break;
+
+	case libcamera::formats::BGR888:
+	case libcamera::formats::RGB888:
+		glActiveTexture(GL_TEXTURE0);
+		configureTexture(*textures_[0]);
+		glTexImage2D(GL_TEXTURE_2D,
+			     0,
+			     GL_RGB,
+			     size_.width(),
+			     size_.height(),
+			     0,
+			     GL_RGB,
+			     GL_UNSIGNED_BYTE,
+			     data_);
+		shaderProgram_.setUniformValue(textureUniformY_, 0);
+		break;
+
 	default:
 		break;
 	};
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list