summaryrefslogtreecommitdiff
path: root/src/qcam/viewfinder_gl.cpp
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-09-06 23:22:54 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-09-22 11:21:49 +0300
commita3b1539869ae53a6446a1c31bdade6560f91a46b (patch)
tree72e66a1f4f06583279ce0f9a012f0512946579d2 /src/qcam/viewfinder_gl.cpp
parent5e1b7a0f6845add01a6d7842ca34f9fbb0712810 (diff)
qcam: viewfinder_gl: Support configurable stride in shaders
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@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Diffstat (limited to 'src/qcam/viewfinder_gl.cpp')
-rw-r--r--src/qcam/viewfinder_gl.cpp54
1 files changed, 43 insertions, 11 deletions
diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp
index aeb1ea02..3ae8b03a 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()