[1/3] qcam: viewfinder_gl: Fix binding of vertex buffer and shader program
diff mbox series

Message ID 20240910234649.28591-2-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • qcam: Fix GL renderer on Qt 6
Related show

Commit Message

Laurent Pinchart Sept. 10, 2024, 11:46 p.m. UTC
Starting in Qt 6.7.0, vertex buffers and shader programs are unbound
just before calling QOpenGLWidget::paintGL(). This breaks rendering in
the GL viewfinder in two ways.

First, we bind the vertex buffer only once at initialization time. There
is therefore no vertex buffer mapped at rendering time, preventing both
the vertex shader from having access to the vertex and texture
coordinates.

Then, we bind the shader program only when rendering the first frame.
There is thus no shader program bound for all subsequent frames,
breaking rendering.

Fix this by binding the vertex buffer where needed, when setting
attribute buffers for the shader program, and binding the shader program
for every frame.

As we use a single vertex buffer, we could bind it at the beginning of
paintGL() and keep it bound indefinitely. That would however fail to
clearly indicate in the source code where the vertex buffer is needed,
making the code more difficult to understand as it would rely on
implicit assumptions. Release the vertex buffer explicitly when we don't
need it anymore to avoid this.

While at it, fix a coding style violation by adding missing curly
brackets.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/apps/qcam/viewfinder_gl.cpp | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

Patch
diff mbox series

diff --git a/src/apps/qcam/viewfinder_gl.cpp b/src/apps/qcam/viewfinder_gl.cpp
index 9d2a69600db1..5be7bec539bf 100644
--- a/src/apps/qcam/viewfinder_gl.cpp
+++ b/src/apps/qcam/viewfinder_gl.cpp
@@ -443,15 +443,11 @@  bool ViewFinderGL::createFragmentShader()
 		close();
 	}
 
-	/* Bind shader pipeline for use */
-	if (!shaderProgram_.bind()) {
-		qWarning() << "[ViewFinderGL]:" << shaderProgram_.log();
-		close();
-	}
-
 	attributeVertex = shaderProgram_.attributeLocation("vertexIn");
 	attributeTexture = shaderProgram_.attributeLocation("textureIn");
 
+	vertexBuffer_.bind();
+
 	shaderProgram_.enableAttributeArray(attributeVertex);
 	shaderProgram_.setAttributeBuffer(attributeVertex,
 					  GL_FLOAT,
@@ -466,6 +462,8 @@  bool ViewFinderGL::createFragmentShader()
 					  2,
 					  2 * sizeof(GLfloat));
 
+	vertexBuffer_.release();
+
 	textureUniformY_ = shaderProgram_.uniformLocation("tex_y");
 	textureUniformU_ = shaderProgram_.uniformLocation("tex_u");
 	textureUniformV_ = shaderProgram_.uniformLocation("tex_v");
@@ -809,11 +807,18 @@  void ViewFinderGL::doRender()
 
 void ViewFinderGL::paintGL()
 {
-	if (!fragmentShader_)
+	if (!fragmentShader_) {
 		if (!createFragmentShader()) {
 			qWarning() << "[ViewFinderGL]:"
 				   << "create fragment shader failed.";
 		}
+	}
+
+	/* Bind shader pipeline for use. */
+	if (!shaderProgram_.bind()) {
+		qWarning() << "[ViewFinderGL]:" << shaderProgram_.log();
+		close();
+	}
 
 	if (image_) {
 		glClearColor(0.0, 0.0, 0.0, 1.0);