cameraview: fix frameskip (#23022)

* fix frameskip

* sync upload->render

* cleanup

* comment

* rename to latest_texture_id
old-commit-hash: 00db14af64
commatwo_master
Dean Lee 3 years ago committed by GitHub
parent 996594fa29
commit 14fa2bf41a
  1. 29
      selfdrive/ui/qt/widgets/cameraview.cc
  2. 4
      selfdrive/ui/qt/widgets/cameraview.h

@ -98,7 +98,6 @@ 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() {
@ -152,7 +151,7 @@ void CameraViewWidget::initializeGL() {
} }
void CameraViewWidget::showEvent(QShowEvent *event) { void CameraViewWidget::showEvent(QShowEvent *event) {
latest_frame = nullptr; latest_texture_id = -1;
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(); });
@ -200,18 +199,17 @@ void CameraViewWidget::updateFrameMat(int w, int h) {
} }
void CameraViewWidget::paintGL() { void CameraViewWidget::paintGL() {
if (!latest_frame) { if (latest_texture_id == -1) {
glClearColor(bg.redF(), bg.greenF(), bg.blueF(), bg.alphaF()); glClearColor(bg.redF(), bg.greenF(), bg.blueF(), bg.alphaF());
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
return; return;
} }
std::unique_lock lk(texture_lock);
glViewport(0, 0, width(), height()); glViewport(0, 0, width(), height());
glBindVertexArray(frame_vao); glBindVertexArray(frame_vao);
glActiveTexture(GL_TEXTURE0); 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()); glUseProgram(program->programId());
glUniform1i(program->uniformLocation("uTexture"), 0); 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); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
assert(glGetError() == GL_NO_ERROR); assert(glGetError() == GL_NO_ERROR);
} }
latest_frame = nullptr; latest_texture_id = -1;
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;
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;
@ -298,8 +291,6 @@ void CameraViewWidget::vipcThread() {
if (VisionBuf *buf = vipc_client->recv(nullptr, 1000)) { if (VisionBuf *buf = vipc_client->recv(nullptr, 1000)) {
if (!Hardware::EON()) { if (!Hardware::EON()) {
std::unique_lock lk(texture_lock);
void *texture_buffer = gl_buffer->map(QOpenGLBuffer::WriteOnly); void *texture_buffer = gl_buffer->map(QOpenGLBuffer::WriteOnly);
memcpy(texture_buffer, buf->addr, buf->len); memcpy(texture_buffer, buf->addr, buf->len);
gl_buffer->unmap(); 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); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, buf->width, buf->height, GL_RGB, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
assert(glGetError() == GL_NO_ERROR); assert(glGetError() == GL_NO_ERROR);
// 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); emit vipcThreadFrameReceived(buf);
glFlush();
} else {
emit vipcThreadFrameReceived(buf);
}
} }
} }
} }

@ -36,7 +36,7 @@ protected:
void vipcThread(); void vipcThread();
bool zoomed_view; bool zoomed_view;
VisionBuf *latest_frame = nullptr; std::atomic<int> latest_texture_id = -1;
GLuint frame_vao, frame_vbo, frame_ibo; GLuint frame_vao, frame_vbo, frame_ibo;
mat4 frame_mat; mat4 frame_mat;
std::unique_ptr<EGLImageTexture> texture[UI_BUF_COUNT]; std::unique_ptr<EGLImageTexture> texture[UI_BUF_COUNT];
@ -49,9 +49,7 @@ protected:
std::atomic<VisionStreamType> stream_type; std::atomic<VisionStreamType> stream_type;
QThread *vipc_thread = nullptr; QThread *vipc_thread = nullptr;
std::mutex texture_lock;
protected slots: protected slots:
void vipcConnected(VisionIpcClient *vipc_client); void vipcConnected(VisionIpcClient *vipc_client);
void vipcFrameReceived(VisionBuf *buf);
}; };

Loading…
Cancel
Save