[libcamera-devel] [PATCH v2 5/5] qcam: viewfinder_gl: Support configurable stride in shaders

paul.elder at ideasonboard.com paul.elder at ideasonboard.com
Wed Sep 22 10:10:15 CEST 2021


Hi Laurent,

On Tue, Sep 07, 2021 at 03:20:44AM +0300, Laurent Pinchart wrote:
> The RGB and YUV conversion doesn't take the stride into account, neither
> when creating the textures, nor when sampling them. Fix it by using the
> stride as the texture width, and multiplying the x coordinate in the
> vertex shaders by a factor to only sample the active portion of the
> image.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

Reviewed-by: Paul Elder <paul.elder at ideasonboard.com>

> ---
>  src/qcam/assets/shader/identity.vert |  4 ++-
>  src/qcam/viewfinder_gl.cpp           | 54 ++++++++++++++++++++++------
>  src/qcam/viewfinder_gl.h             |  1 +
>  3 files changed, 47 insertions(+), 12 deletions(-)
> 
> diff --git a/src/qcam/assets/shader/identity.vert b/src/qcam/assets/shader/identity.vert
> index 6d6f7551017e..12c41377cfe7 100644
> --- a/src/qcam/assets/shader/identity.vert
> +++ b/src/qcam/assets/shader/identity.vert
> @@ -9,8 +9,10 @@ attribute vec4 vertexIn;
>  attribute vec2 textureIn;
>  varying vec2 textureOut;
>  
> +uniform float stride_factor;
> +
>  void main(void)
>  {
>  	gl_Position = vertexIn;
> -	textureOut = textureIn;
> +	textureOut = vec2(textureIn.x * stride_factor, textureIn.y);
>  }
> diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp
> index aeb1ea02d2d5..3ae8b03accb5 100644
> --- a/src/qcam/viewfinder_gl.cpp
> +++ b/src/qcam/viewfinder_gl.cpp
> @@ -395,6 +395,7 @@ bool ViewFinderGL::createFragmentShader()
>  	textureUniformV_ = shaderProgram_.uniformLocation("tex_v");
>  	textureUniformStep_ = shaderProgram_.uniformLocation("tex_step");
>  	textureUniformSize_ = shaderProgram_.uniformLocation("tex_size");
> +	textureUniformStrideFactor_ = shaderProgram_.uniformLocation("stride_factor");
>  	textureUniformBayerFirstRed_ = shaderProgram_.uniformLocation("tex_bayer_first_red");
>  
>  	/* Create the textures. */
> @@ -464,6 +465,9 @@ void ViewFinderGL::initializeGL()
>  
>  void ViewFinderGL::doRender()
>  {
> +	/* Stride of the first plane, in pixels. */
> +	unsigned int stridePixels;
> +
>  	switch (format_) {
>  	case libcamera::formats::NV12:
>  	case libcamera::formats::NV21:
> @@ -477,7 +481,7 @@ void ViewFinderGL::doRender()
>  		glTexImage2D(GL_TEXTURE_2D,
>  			     0,
>  			     GL_LUMINANCE,
> -			     size_.width(),
> +			     stride_,
>  			     size_.height(),
>  			     0,
>  			     GL_LUMINANCE,
> @@ -491,13 +495,15 @@ void ViewFinderGL::doRender()
>  		glTexImage2D(GL_TEXTURE_2D,
>  			     0,
>  			     GL_LUMINANCE_ALPHA,
> -			     size_.width() / horzSubSample_,
> +			     stride_ / horzSubSample_,
>  			     size_.height() / vertSubSample_,
>  			     0,
>  			     GL_LUMINANCE_ALPHA,
>  			     GL_UNSIGNED_BYTE,
>  			     image_->data(1).data());
>  		shaderProgram_.setUniformValue(textureUniformU_, 1);
> +
> +		stridePixels = stride_;
>  		break;
>  
>  	case libcamera::formats::YUV420:
> @@ -507,7 +513,7 @@ void ViewFinderGL::doRender()
>  		glTexImage2D(GL_TEXTURE_2D,
>  			     0,
>  			     GL_LUMINANCE,
> -			     size_.width(),
> +			     stride_,
>  			     size_.height(),
>  			     0,
>  			     GL_LUMINANCE,
> @@ -521,7 +527,7 @@ void ViewFinderGL::doRender()
>  		glTexImage2D(GL_TEXTURE_2D,
>  			     0,
>  			     GL_LUMINANCE,
> -			     size_.width() / horzSubSample_,
> +			     stride_ / horzSubSample_,
>  			     size_.height() / vertSubSample_,
>  			     0,
>  			     GL_LUMINANCE,
> @@ -535,13 +541,15 @@ void ViewFinderGL::doRender()
>  		glTexImage2D(GL_TEXTURE_2D,
>  			     0,
>  			     GL_LUMINANCE,
> -			     size_.width() / horzSubSample_,
> +			     stride_ / horzSubSample_,
>  			     size_.height() / vertSubSample_,
>  			     0,
>  			     GL_LUMINANCE,
>  			     GL_UNSIGNED_BYTE,
>  			     image_->data(2).data());
>  		shaderProgram_.setUniformValue(textureUniformV_, 2);
> +
> +		stridePixels = stride_;
>  		break;
>  
>  	case libcamera::formats::YVU420:
> @@ -551,7 +559,7 @@ void ViewFinderGL::doRender()
>  		glTexImage2D(GL_TEXTURE_2D,
>  			     0,
>  			     GL_LUMINANCE,
> -			     size_.width(),
> +			     stride_,
>  			     size_.height(),
>  			     0,
>  			     GL_LUMINANCE,
> @@ -565,7 +573,7 @@ void ViewFinderGL::doRender()
>  		glTexImage2D(GL_TEXTURE_2D,
>  			     0,
>  			     GL_LUMINANCE,
> -			     size_.width() / horzSubSample_,
> +			     stride_ / horzSubSample_,
>  			     size_.height() / vertSubSample_,
>  			     0,
>  			     GL_LUMINANCE,
> @@ -579,13 +587,15 @@ void ViewFinderGL::doRender()
>  		glTexImage2D(GL_TEXTURE_2D,
>  			     0,
>  			     GL_LUMINANCE,
> -			     size_.width() / horzSubSample_,
> +			     stride_ / horzSubSample_,
>  			     size_.height() / vertSubSample_,
>  			     0,
>  			     GL_LUMINANCE,
>  			     GL_UNSIGNED_BYTE,
>  			     image_->data(2).data());
>  		shaderProgram_.setUniformValue(textureUniformU_, 1);
> +
> +		stridePixels = stride_;
>  		break;
>  
>  	case libcamera::formats::UYVY:
> @@ -602,7 +612,7 @@ void ViewFinderGL::doRender()
>  		glTexImage2D(GL_TEXTURE_2D,
>  			     0,
>  			     GL_RGBA,
> -			     size_.width() / 2,
> +			     stride_ / 4,
>  			     size_.height(),
>  			     0,
>  			     GL_RGBA,
> @@ -619,6 +629,8 @@ void ViewFinderGL::doRender()
>  		shaderProgram_.setUniformValue(textureUniformStep_,
>  					       1.0f / (size_.width() / 2 - 1),
>  					       1.0f /* not used */);
> +
> +		stridePixels = stride_ / 2;
>  		break;
>  
>  	case libcamera::formats::ABGR8888:
> @@ -630,13 +642,15 @@ void ViewFinderGL::doRender()
>  		glTexImage2D(GL_TEXTURE_2D,
>  			     0,
>  			     GL_RGBA,
> -			     size_.width(),
> +			     stride_ / 4,
>  			     size_.height(),
>  			     0,
>  			     GL_RGBA,
>  			     GL_UNSIGNED_BYTE,
>  			     image_->data(0).data());
>  		shaderProgram_.setUniformValue(textureUniformY_, 0);
> +
> +		stridePixels = stride_ / 4;
>  		break;
>  
>  	case libcamera::formats::BGR888:
> @@ -646,13 +660,15 @@ void ViewFinderGL::doRender()
>  		glTexImage2D(GL_TEXTURE_2D,
>  			     0,
>  			     GL_RGB,
> -			     size_.width(),
> +			     stride_ / 3,
>  			     size_.height(),
>  			     0,
>  			     GL_RGB,
>  			     GL_UNSIGNED_BYTE,
>  			     image_->data(0).data());
>  		shaderProgram_.setUniformValue(textureUniformY_, 0);
> +
> +		stridePixels = stride_ / 3;
>  		break;
>  
>  	case libcamera::formats::SBGGR8:
> @@ -692,11 +708,27 @@ void ViewFinderGL::doRender()
>  		shaderProgram_.setUniformValue(textureUniformStep_,
>  					       1.0f / (stride_ - 1),
>  					       1.0f / (size_.height() - 1));
> +
> +		/*
> +		 * The stride is already taken into account in the shaders, set
> +		 * the generic stride factor to 1.0.
> +		 */
> +		stridePixels = size_.width();
>  		break;
>  
>  	default:
> +		stridePixels = size_.width();
>  		break;
>  	};
> +
> +	/*
> +	 * Compute the stride factor for the vertex shader, to map the
> +	 * horizontal texture coordinate range [0.0, 1.0] to the active portion
> +	 * of the image.
> +	 */
> +	shaderProgram_.setUniformValue(textureUniformStrideFactor_,
> +				       static_cast<float>(size_.width() - 1) /
> +				       (stridePixels - 1));
>  }
>  
>  void ViewFinderGL::paintGL()
> diff --git a/src/qcam/viewfinder_gl.h b/src/qcam/viewfinder_gl.h
> index 2b2b1e86035a..37b1ddd04b1d 100644
> --- a/src/qcam/viewfinder_gl.h
> +++ b/src/qcam/viewfinder_gl.h
> @@ -97,6 +97,7 @@ private:
>  
>  	/* Raw Bayer texture parameters */
>  	GLuint textureUniformSize_;
> +	GLuint textureUniformStrideFactor_;
>  	GLuint textureUniformBayerFirstRed_;
>  	QPointF firstRed_;
>  
> -- 
> Regards,
> 
> Laurent Pinchart
> 


More information about the libcamera-devel mailing list