| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -102,6 +102,7 @@ CameraViewWidget::CameraViewWidget(std::string stream_name, VisionStreamType typ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                   stream_name(stream_name), stream_type(type), zoomed_view(zoom), QOpenGLWidget(parent) { | 
					 | 
					 | 
					 | 
					                                   stream_name(stream_name), stream_type(type), zoomed_view(zoom), QOpenGLWidget(parent) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  setAttribute(Qt::WA_OpaquePaintEvent); | 
					 | 
					 | 
					 | 
					  setAttribute(Qt::WA_OpaquePaintEvent); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  connect(this, &CameraViewWidget::vipcThreadConnected, this, &CameraViewWidget::vipcConnected, Qt::BlockingQueuedConnection); | 
					 | 
					 | 
					 | 
					  connect(this, &CameraViewWidget::vipcThreadConnected, this, &CameraViewWidget::vipcConnected, Qt::BlockingQueuedConnection); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  connect(this, &CameraViewWidget::vipcThreadFrameReceived, this, &CameraViewWidget::vipcFrameReceived); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					CameraViewWidget::~CameraViewWidget() { | 
					 | 
					 | 
					 | 
					CameraViewWidget::~CameraViewWidget() { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -162,7 +163,7 @@ void CameraViewWidget::initializeGL() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void CameraViewWidget::showEvent(QShowEvent *event) { | 
					 | 
					 | 
					 | 
					void CameraViewWidget::showEvent(QShowEvent *event) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  latest_texture_id = -1; | 
					 | 
					 | 
					 | 
					  latest_frame = nullptr; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if (!vipc_thread) { | 
					 | 
					 | 
					 | 
					  if (!vipc_thread) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    vipc_thread = new QThread(); | 
					 | 
					 | 
					 | 
					    vipc_thread = new QThread(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    connect(vipc_thread, &QThread::started, [=]() { vipcThread(); }); | 
					 | 
					 | 
					 | 
					    connect(vipc_thread, &QThread::started, [=]() { vipcThread(); }); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -215,7 +216,7 @@ void CameraViewWidget::paintGL() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  std::lock_guard lk(lock); | 
					 | 
					 | 
					 | 
					  std::lock_guard lk(lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if (latest_texture_id == -1) return; | 
					 | 
					 | 
					 | 
					  if (latest_frame == nullptr) return; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  glViewport(0, 0, width(), height()); | 
					 | 
					 | 
					 | 
					  glViewport(0, 0, width(), height()); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  // sync with the PBO
 | 
					 | 
					 | 
					 | 
					  // sync with the PBO
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -226,9 +227,13 @@ void CameraViewWidget::paintGL() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  glBindVertexArray(frame_vao); | 
					 | 
					 | 
					 | 
					  glBindVertexArray(frame_vao); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  glUseProgram(program->programId()); | 
					 | 
					 | 
					 | 
					  glUseProgram(program->programId()); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  uint8_t *address[3] = {latest_frame->y, latest_frame->u, latest_frame->v}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  for (int i = 0; i < 3; ++i) { | 
					 | 
					 | 
					 | 
					  for (int i = 0; i < 3; ++i) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    glActiveTexture(GL_TEXTURE0 + i); | 
					 | 
					 | 
					 | 
					    glActiveTexture(GL_TEXTURE0 + i); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    glBindTexture(GL_TEXTURE_2D, textures[i]); | 
					 | 
					 | 
					 | 
					    glBindTexture(GL_TEXTURE_2D, textures[i]); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    int width = i == 0 ? stream_width : stream_width / 2; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    int height = i == 0 ? stream_height : stream_height / 2; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, address[i]); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    assert(glGetError() == GL_NO_ERROR); | 
					 | 
					 | 
					 | 
					    assert(glGetError() == GL_NO_ERROR); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -244,7 +249,7 @@ void CameraViewWidget::paintGL() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void CameraViewWidget::vipcConnected(VisionIpcClient *vipc_client) { | 
					 | 
					 | 
					 | 
					void CameraViewWidget::vipcConnected(VisionIpcClient *vipc_client) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  makeCurrent(); | 
					 | 
					 | 
					 | 
					  makeCurrent(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  latest_texture_id = -1; | 
					 | 
					 | 
					 | 
					  latest_frame = nullptr; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  stream_width = vipc_client->buffers[0].width; | 
					 | 
					 | 
					 | 
					  stream_width = vipc_client->buffers[0].width; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  stream_height = vipc_client->buffers[0].height; | 
					 | 
					 | 
					 | 
					  stream_height = vipc_client->buffers[0].height; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -264,27 +269,15 @@ void CameraViewWidget::vipcConnected(VisionIpcClient *vipc_client) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  updateFrameMat(width(), height()); | 
					 | 
					 | 
					 | 
					  updateFrameMat(width(), height()); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					void CameraViewWidget::vipcFrameReceived(VisionBuf *buf) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  latest_frame = buf; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  update(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void CameraViewWidget::vipcThread() { | 
					 | 
					 | 
					 | 
					void CameraViewWidget::vipcThread() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  VisionStreamType cur_stream_type = stream_type; | 
					 | 
					 | 
					 | 
					  VisionStreamType cur_stream_type = stream_type; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  std::unique_ptr<VisionIpcClient> vipc_client; | 
					 | 
					 | 
					 | 
					  std::unique_ptr<VisionIpcClient> vipc_client; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  std::unique_ptr<QOpenGLContext> ctx; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  std::unique_ptr<QOffscreenSurface> surface; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  std::unique_ptr<QOpenGLBuffer> gl_buffer; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  ctx = std::make_unique<QOpenGLContext>(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  ctx->setFormat(context()->format()); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  ctx->setShareContext(context()); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  ctx->create(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  assert(ctx->isValid()); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  surface = std::make_unique<QOffscreenSurface>(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  surface->setFormat(ctx->format()); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  surface->create(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  ctx->makeCurrent(surface.get()); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  assert(QOpenGLContext::currentContext() == ctx.get()); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  initializeOpenGLFunctions(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  while (!QThread::currentThread()->isInterruptionRequested()) { | 
					 | 
					 | 
					 | 
					  while (!QThread::currentThread()->isInterruptionRequested()) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (!vipc_client || cur_stream_type != stream_type) { | 
					 | 
					 | 
					 | 
					    if (!vipc_client || cur_stream_type != stream_type) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      cur_stream_type = stream_type; | 
					 | 
					 | 
					 | 
					      cur_stream_type = stream_type; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -296,54 +289,10 @@ void CameraViewWidget::vipcThread() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        QThread::msleep(100); | 
					 | 
					 | 
					 | 
					        QThread::msleep(100); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        continue; | 
					 | 
					 | 
					 | 
					        continue; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      gl_buffer.reset(new QOpenGLBuffer(QOpenGLBuffer::PixelUnpackBuffer)); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      gl_buffer->create(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      gl_buffer->bind(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      gl_buffer->setUsagePattern(QOpenGLBuffer::StreamDraw); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      gl_buffer->allocate(vipc_client->buffers[0].len); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      emit vipcThreadConnected(vipc_client.get()); | 
					 | 
					 | 
					 | 
					      emit vipcThreadConnected(vipc_client.get()); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (VisionBuf *buf = vipc_client->recv(nullptr, 1000)) { | 
					 | 
					 | 
					 | 
					    if (VisionBuf *buf = vipc_client->recv(nullptr, 1000)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        std::lock_guard lk(lock); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for (int i = 0; i < 3; i++) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          void *texture_buffer = gl_buffer->map(QOpenGLBuffer::WriteOnly); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if (texture_buffer == nullptr) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            LOGE("gl_buffer->map returned nullptr"); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            continue; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          int width = i == 0 ? stream_width : stream_width / 2; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          int height = i == 0 ? stream_height : stream_height / 2; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          uint8_t* tex_buf[] = {buf->y, buf->u, buf->v}; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          memcpy(texture_buffer, tex_buf[i], width*height); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          gl_buffer->unmap(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          // copy pixels from PBO to texture object
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          glBindTexture(GL_TEXTURE_2D, textures[i]); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        glBindTexture(GL_TEXTURE_2D, 0); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        assert(glGetError() == GL_NO_ERROR); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        wait_fence.reset(new WaitFence()); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // Ensure the fence is in the GPU command queue, or waiting on it might block
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // https://www.khronos.org/opengl/wiki/Sync_Object#Flushing_and_contexts
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        glFlush(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        latest_texture_id = buf->idx; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      // Schedule update. update() will be invoked on the gui thread.
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      QMetaObject::invokeMethod(this, "update"); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      // TODO: remove later, it's only connected by DriverView.
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      emit vipcThreadFrameReceived(buf); | 
					 | 
					 | 
					 | 
					      emit vipcThreadFrameReceived(buf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |