[libcamera-devel] [PATCH] qcam: Support OpenGL ES 2.0

Laurent Pinchart laurent.pinchart at ideasonboard.com
Tue Aug 3 11:23:10 CEST 2021


The GL_RG and GL_RED texture formats are not supported in OpenGL ES
prior to 3.0. In order to be compatible with OpenGL ES 2.0, use
GL_LUMINANCE_ALPHA and GL_LUMINANCE instead. The shader code needs to be
updated accordingly for GL_RG, as the second component is now stored in
alpha component instead of the green component. Usage of the red
component is fine, the luminance value is stored in the red, green and
blue components.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
Tested with vivid, using NV12, YV420, YVU420 and SGRBG8, which should
cover all code paths.
---
 src/qcam/assets/shader/YUV_2_planes.frag |  4 +--
 src/qcam/viewfinder_gl.cpp               | 40 ++++++++++++------------
 2 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/qcam/assets/shader/YUV_2_planes.frag b/src/qcam/assets/shader/YUV_2_planes.frag
index 125f1c850a33..254463c05cac 100644
--- a/src/qcam/assets/shader/YUV_2_planes.frag
+++ b/src/qcam/assets/shader/YUV_2_planes.frag
@@ -26,9 +26,9 @@ 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;
+	yuv.z = texture2D(tex_u, textureOut).a - 0.500;
 #elif defined(YUV_PATTERN_VU)
-	yuv.y = texture2D(tex_u, textureOut).g - 0.500;
+	yuv.y = texture2D(tex_u, textureOut).a - 0.500;
 	yuv.z = texture2D(tex_u, textureOut).r - 0.500;
 #else
 #error Invalid pattern
diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp
index e7c8620c7024..77a6437e56fd 100644
--- a/src/qcam/viewfinder_gl.cpp
+++ b/src/qcam/viewfinder_gl.cpp
@@ -481,11 +481,11 @@ void ViewFinderGL::doRender()
 		configureTexture(*textures_[0]);
 		glTexImage2D(GL_TEXTURE_2D,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     size_.width(),
 			     size_.height(),
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     GL_UNSIGNED_BYTE,
 			     data_);
 		shaderProgram_.setUniformValue(textureUniformY_, 0);
@@ -495,11 +495,11 @@ void ViewFinderGL::doRender()
 		configureTexture(*textures_[1]);
 		glTexImage2D(GL_TEXTURE_2D,
 			     0,
-			     GL_RG,
+			     GL_LUMINANCE_ALPHA,
 			     size_.width() / horzSubSample_,
 			     size_.height() / vertSubSample_,
 			     0,
-			     GL_RG,
+			     GL_LUMINANCE_ALPHA,
 			     GL_UNSIGNED_BYTE,
 			     data_ + size_.width() * size_.height());
 		shaderProgram_.setUniformValue(textureUniformU_, 1);
@@ -511,11 +511,11 @@ void ViewFinderGL::doRender()
 		configureTexture(*textures_[0]);
 		glTexImage2D(GL_TEXTURE_2D,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     size_.width(),
 			     size_.height(),
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     GL_UNSIGNED_BYTE,
 			     data_);
 		shaderProgram_.setUniformValue(textureUniformY_, 0);
@@ -525,11 +525,11 @@ void ViewFinderGL::doRender()
 		configureTexture(*textures_[1]);
 		glTexImage2D(GL_TEXTURE_2D,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     size_.width() / horzSubSample_,
 			     size_.height() / vertSubSample_,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     GL_UNSIGNED_BYTE,
 			     data_ + size_.width() * size_.height());
 		shaderProgram_.setUniformValue(textureUniformU_, 1);
@@ -539,11 +539,11 @@ void ViewFinderGL::doRender()
 		configureTexture(*textures_[2]);
 		glTexImage2D(GL_TEXTURE_2D,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     size_.width() / horzSubSample_,
 			     size_.height() / vertSubSample_,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     GL_UNSIGNED_BYTE,
 			     data_ + size_.width() * size_.height() * 5 / 4);
 		shaderProgram_.setUniformValue(textureUniformV_, 2);
@@ -555,11 +555,11 @@ void ViewFinderGL::doRender()
 		configureTexture(*textures_[0]);
 		glTexImage2D(GL_TEXTURE_2D,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     size_.width(),
 			     size_.height(),
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     GL_UNSIGNED_BYTE,
 			     data_);
 		shaderProgram_.setUniformValue(textureUniformY_, 0);
@@ -569,11 +569,11 @@ void ViewFinderGL::doRender()
 		configureTexture(*textures_[2]);
 		glTexImage2D(GL_TEXTURE_2D,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     size_.width() / horzSubSample_,
 			     size_.height() / vertSubSample_,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     GL_UNSIGNED_BYTE,
 			     data_ + size_.width() * size_.height());
 		shaderProgram_.setUniformValue(textureUniformV_, 2);
@@ -583,11 +583,11 @@ void ViewFinderGL::doRender()
 		configureTexture(*textures_[1]);
 		glTexImage2D(GL_TEXTURE_2D,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     size_.width() / horzSubSample_,
 			     size_.height() / vertSubSample_,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     GL_UNSIGNED_BYTE,
 			     data_ + size_.width() * size_.height() * 5 / 4);
 		shaderProgram_.setUniformValue(textureUniformU_, 1);
@@ -674,18 +674,18 @@ void ViewFinderGL::doRender()
 	case libcamera::formats::SRGGB12_CSI2P:
 		/*
 		 * Raw Bayer 8-bit, and packed raw Bayer 10-bit/12-bit formats
-		 * are stored in GL_RED texture.
-		 * The texture width is equal to the stride.
+		 * are stored in GL_LUMINANCE texture. The texture width is
+		 * equal to the stride.
 		 */
 		glActiveTexture(GL_TEXTURE0);
 		configureTexture(*textures_[0]);
 		glTexImage2D(GL_TEXTURE_2D,
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     stride_,
 			     size_.height(),
 			     0,
-			     GL_RED,
+			     GL_LUMINANCE,
 			     GL_UNSIGNED_BYTE,
 			     data_);
 		shaderProgram_.setUniformValue(textureUniformY_, 0);
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list