[libcamera-devel] [PATCH 5/7] qcam: viewfinder_gl: Support #define in shaders

Laurent Pinchart laurent.pinchart at ideasonboard.com
Wed Sep 16 16:52:52 CEST 2020


Prepare the infrastructure to support defining preprocessor macros in
shaders:

- Rename the fragmentShaderSrc_ member to fragmentShaderFile_ to reflect
  better that it contains a file name, not shader source code
- Add a new fragmentShaderDefines_ member to store preprocessor macros
- Prepend the macros to the shader source before compiling it

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/qcam/viewfinder_gl.cpp | 42 +++++++++++++++++++++++++++-----------
 src/qcam/viewfinder_gl.h   | 11 +++++-----
 2 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp
index 0fa06a290959..7cb5fb63656f 100644
--- a/src/qcam/viewfinder_gl.cpp
+++ b/src/qcam/viewfinder_gl.cpp
@@ -7,6 +7,8 @@
 
 #include "viewfinder_gl.h"
 
+#include <QByteArray>
+#include <QFile>
 #include <QImage>
 
 #include <libcamera/formats.h>
@@ -24,7 +26,7 @@ static const QList<libcamera::PixelFormat> supportedFormats{
 
 ViewFinderGL::ViewFinderGL(QWidget *parent)
 	: QOpenGLWidget(parent), buffer_(nullptr), yuvData_(nullptr),
-	  fragmentShader_(nullptr), vertexShader_(nullptr),
+	  vertexShader_(nullptr), fragmentShader_(nullptr),
 	  vertexBuffer_(QOpenGLBuffer::VertexBuffer),
 	  textureU_(QOpenGLTexture::Target2D),
 	  textureV_(QOpenGLTexture::Target2D),
@@ -97,46 +99,49 @@ void ViewFinderGL::render(libcamera::FrameBuffer *buffer, MappedBuffer *map)
 bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format)
 {
 	bool ret = true;
+
+	fragmentShaderDefines_.clear();
+
 	switch (format) {
 	case libcamera::formats::NV12:
 		horzSubSample_ = 2;
 		vertSubSample_ = 2;
-		fragmentShaderSrc_ = ":YUV_2_planes_UV.frag";
+		fragmentShaderFile_ = ":YUV_2_planes_UV.frag";
 		break;
 	case libcamera::formats::NV21:
 		horzSubSample_ = 2;
 		vertSubSample_ = 2;
-		fragmentShaderSrc_ = ":YUV_2_planes_VU.frag";
+		fragmentShaderFile_ = ":YUV_2_planes_VU.frag";
 		break;
 	case libcamera::formats::NV16:
 		horzSubSample_ = 2;
 		vertSubSample_ = 1;
-		fragmentShaderSrc_ = ":YUV_2_planes_UV.frag";
+		fragmentShaderFile_ = ":YUV_2_planes_UV.frag";
 		break;
 	case libcamera::formats::NV61:
 		horzSubSample_ = 2;
 		vertSubSample_ = 1;
-		fragmentShaderSrc_ = ":YUV_2_planes_VU.frag";
+		fragmentShaderFile_ = ":YUV_2_planes_VU.frag";
 		break;
 	case libcamera::formats::NV24:
 		horzSubSample_ = 1;
 		vertSubSample_ = 1;
-		fragmentShaderSrc_ = ":YUV_2_planes_UV.frag";
+		fragmentShaderFile_ = ":YUV_2_planes_UV.frag";
 		break;
 	case libcamera::formats::NV42:
 		horzSubSample_ = 1;
 		vertSubSample_ = 1;
-		fragmentShaderSrc_ = ":YUV_2_planes_VU.frag";
+		fragmentShaderFile_ = ":YUV_2_planes_VU.frag";
 		break;
 	case libcamera::formats::YUV420:
 		horzSubSample_ = 2;
 		vertSubSample_ = 2;
-		fragmentShaderSrc_ = ":YUV_3_planes.frag";
+		fragmentShaderFile_ = ":YUV_3_planes.frag";
 		break;
 	case libcamera::formats::YVU420:
 		horzSubSample_ = 2;
 		vertSubSample_ = 2;
-		fragmentShaderSrc_ = ":YUV_3_planes.frag";
+		fragmentShaderFile_ = ":YUV_3_planes.frag";
 		break;
 	default:
 		ret = false;
@@ -168,11 +173,24 @@ bool ViewFinderGL::createFragmentShader()
 	int attributeVertex;
 	int attributeTexture;
 
-	/* Create Fragment Shader */
+	/*
+	 * Create the fragment shader, compile it, and add it to the shader
+	 * program. The #define macros stored in fragmentShaderDefines_, if
+	 * any, are prepended to the source code.
+	 */
 	fragmentShader_ = new QOpenGLShader(QOpenGLShader::Fragment, this);
 
-	/* Compile the fragment shader */
-	if (!fragmentShader_->compileSourceFile(fragmentShaderSrc_)) {
+	QFile file(fragmentShaderFile_);
+	if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+		qWarning() << "Shader" << fragmentShaderFile_ << "not found";
+		return false;
+	}
+
+	QString defines = fragmentShaderDefines_.join('\n') + "\n";
+	QByteArray src = file.readAll();
+	src.prepend(defines.toUtf8());
+
+	if (!fragmentShader_->compileSourceCode(src)) {
 		qWarning() << "[ViewFinderGL]:" << fragmentShader_->log();
 		return false;
 	}
diff --git a/src/qcam/viewfinder_gl.h b/src/qcam/viewfinder_gl.h
index 7675d0a06351..53424dc10bc5 100644
--- a/src/qcam/viewfinder_gl.h
+++ b/src/qcam/viewfinder_gl.h
@@ -65,17 +65,16 @@ private:
 	QSize size_;
 	unsigned char *yuvData_;
 
-	/* OpenGL components for rendering */
-	QOpenGLShader *fragmentShader_;
-	QOpenGLShader *vertexShader_;
+	/* Shaders */
 	QOpenGLShaderProgram shaderProgram_;
+	QOpenGLShader *vertexShader_;
+	QOpenGLShader *fragmentShader_;
+	QString fragmentShaderFile_;
+	QStringList fragmentShaderDefines_;
 
 	/* Vertex buffer */
 	QOpenGLBuffer vertexBuffer_;
 
-	/* Fragment shader file name */
-	QString fragmentShaderSrc_;
-
 	/* YUV texture planars and parameters */
 	GLuint textureUniformU_;
 	GLuint textureUniformV_;
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list