diff --git a/selfdrive/ui/qt/widgets/cameraview.cc b/selfdrive/ui/qt/widgets/cameraview.cc index 240e4c837d..6b25c49237 100644 --- a/selfdrive/ui/qt/widgets/cameraview.cc +++ b/selfdrive/ui/qt/widgets/cameraview.cc @@ -98,7 +98,6 @@ CameraViewWidget::CameraViewWidget(std::string stream_name, VisionStreamType typ stream_name(stream_name), stream_type(type), zoomed_view(zoom), QOpenGLWidget(parent) { setAttribute(Qt::WA_OpaquePaintEvent); connect(this, &CameraViewWidget::vipcThreadConnected, this, &CameraViewWidget::vipcConnected, Qt::BlockingQueuedConnection); - connect(this, &CameraViewWidget::vipcThreadFrameReceived, this, &CameraViewWidget::vipcFrameReceived); } CameraViewWidget::~CameraViewWidget() { @@ -152,7 +151,7 @@ void CameraViewWidget::initializeGL() { } void CameraViewWidget::showEvent(QShowEvent *event) { - latest_frame = nullptr; + latest_texture_id = -1; if (!vipc_thread) { vipc_thread = new QThread(); connect(vipc_thread, &QThread::started, [=]() { vipcThread(); }); @@ -200,18 +199,17 @@ void CameraViewWidget::updateFrameMat(int w, int h) { } void CameraViewWidget::paintGL() { - if (!latest_frame) { + if (latest_texture_id == -1) { glClearColor(bg.redF(), bg.greenF(), bg.blueF(), bg.alphaF()); glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); return; } - std::unique_lock lk(texture_lock); glViewport(0, 0, width(), height()); glBindVertexArray(frame_vao); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture[latest_frame->idx]->frame_tex); + glBindTexture(GL_TEXTURE_2D, texture[latest_texture_id]->frame_tex); glUseProgram(program->programId()); glUniform1i(program->uniformLocation("uTexture"), 0); @@ -239,17 +237,12 @@ void CameraViewWidget::vipcConnected(VisionIpcClient *vipc_client) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); assert(glGetError() == GL_NO_ERROR); } - latest_frame = nullptr; + latest_texture_id = -1; stream_width = vipc_client->buffers[0].width; stream_height = vipc_client->buffers[0].height; updateFrameMat(width(), height()); } -void CameraViewWidget::vipcFrameReceived(VisionBuf *buf) { - latest_frame = buf; - update(); -} - void CameraViewWidget::vipcThread() { VisionStreamType cur_stream_type = stream_type; std::unique_ptr vipc_client; @@ -298,8 +291,6 @@ void CameraViewWidget::vipcThread() { if (VisionBuf *buf = vipc_client->recv(nullptr, 1000)) { if (!Hardware::EON()) { - std::unique_lock lk(texture_lock); - void *texture_buffer = gl_buffer->map(QOpenGLBuffer::WriteOnly); memcpy(texture_buffer, buf->addr, buf->len); gl_buffer->unmap(); @@ -309,13 +300,15 @@ void CameraViewWidget::vipcThread() { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, buf->width, buf->height, GL_RGB, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); assert(glGetError() == GL_NO_ERROR); - - emit vipcThreadFrameReceived(buf); - - glFlush(); - } else { - emit vipcThreadFrameReceived(buf); + // use glFinish to ensure that the texture has been uploaded. + glFinish(); } + 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); } } } diff --git a/selfdrive/ui/qt/widgets/cameraview.h b/selfdrive/ui/qt/widgets/cameraview.h index 5e0fc1300b..fb69fcae59 100644 --- a/selfdrive/ui/qt/widgets/cameraview.h +++ b/selfdrive/ui/qt/widgets/cameraview.h @@ -36,7 +36,7 @@ protected: void vipcThread(); bool zoomed_view; - VisionBuf *latest_frame = nullptr; + std::atomic latest_texture_id = -1; GLuint frame_vao, frame_vbo, frame_ibo; mat4 frame_mat; std::unique_ptr texture[UI_BUF_COUNT]; @@ -49,9 +49,7 @@ protected: std::atomic stream_type; QThread *vipc_thread = nullptr; - std::mutex texture_lock; protected slots: void vipcConnected(VisionIpcClient *vipc_client); - void vipcFrameReceived(VisionBuf *buf); };