[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