[libcamera-devel] [PATCH v2 5/5] qcam: viewfinder_gl: Support configurable stride in shaders
Kieran Bingham
kieran.bingham at ideasonboard.com
Tue Sep 21 17:38:08 CEST 2021
On 07/09/2021 01:20, 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>
A somewhat not-particularly-confident, but no disagreement:
Reviewed-by: Kieran Bingham <kieran.bingham 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_;
>
>
More information about the libcamera-devel
mailing list