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

Niklas Söderlund niklas.soderlund at ragnatech.se
Wed Sep 16 17:23:19 CEST 2020


Hi Laurent,

Thanks for your work.

On 2020-09-16 17:52:52 +0300, Laurent Pinchart wrote:
> 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>

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

> ---
>  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
> 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

-- 
Regards,
Niklas Söderlund


More information about the libcamera-devel mailing list