@@ -202,9 +202,15 @@ void CameraViewWidget::paintGL() {
202202 glClearColor (bg.redF (), bg.greenF (), bg.blueF (), bg.alphaF ());
203203 glClear (GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
204204
205+ std::lock_guard lk (lock);
206+
205207 if (latest_texture_id == -1 ) return ;
206208
207209 glViewport (0 , 0 , width (), height ());
210+ // sync with the PBO
211+ if (wait_fence) {
212+ wait_fence->wait ();
213+ }
208214
209215 glBindVertexArray (frame_vao);
210216 glActiveTexture (GL_TEXTURE0);
@@ -289,26 +295,33 @@ void CameraViewWidget::vipcThread() {
289295 }
290296
291297 if (VisionBuf *buf = vipc_client->recv (nullptr , 1000 )) {
292- if (!Hardware::EON ()) {
293- void *texture_buffer = gl_buffer->map (QOpenGLBuffer::WriteOnly);
294-
295- if (texture_buffer == nullptr ) {
296- LOGE (" gl_buffer->map returned nullptr" );
297- continue ;
298+ {
299+ std::lock_guard lk (lock);
300+ if (!Hardware::EON ()) {
301+ void *texture_buffer = gl_buffer->map (QOpenGLBuffer::WriteOnly);
302+
303+ if (texture_buffer == nullptr ) {
304+ LOGE (" gl_buffer->map returned nullptr" );
305+ continue ;
306+ }
307+
308+ memcpy (texture_buffer, buf->addr , buf->len );
309+ gl_buffer->unmap ();
310+
311+ // copy pixels from PBO to texture object
312+ glBindTexture (GL_TEXTURE_2D, texture[buf->idx ]->frame_tex );
313+ glTexSubImage2D (GL_TEXTURE_2D, 0 , 0 , 0 , buf->width , buf->height , GL_RGB, GL_UNSIGNED_BYTE, 0 );
314+ glBindTexture (GL_TEXTURE_2D, 0 );
315+ assert (glGetError () == GL_NO_ERROR);
316+
317+ wait_fence.reset (new WaitFence ());
318+
319+ // Ensure the fence is in the GPU command queue, or waiting on it might block
320+ // https://www.khronos.org/opengl/wiki/Sync_Object#Flushing_and_contexts
321+ glFlush ();
298322 }
299-
300- memcpy (texture_buffer, buf->addr , buf->len );
301- gl_buffer->unmap ();
302-
303- // copy pixels from PBO to texture object
304- glBindTexture (GL_TEXTURE_2D, texture[buf->idx ]->frame_tex );
305- glTexSubImage2D (GL_TEXTURE_2D, 0 , 0 , 0 , buf->width , buf->height , GL_RGB, GL_UNSIGNED_BYTE, 0 );
306- glBindTexture (GL_TEXTURE_2D, 0 );
307- assert (glGetError () == GL_NO_ERROR);
308- // use glFinish to ensure that the texture has been uploaded.
309- glFinish ();
323+ latest_texture_id = buf->idx ;
310324 }
311- latest_texture_id = buf->idx ;
312325 // Schedule update. update() will be invoked on the gui thread.
313326 QMetaObject::invokeMethod (this , " update" );
314327
0 commit comments