Skip to content

Commit d77782e

Browse files
pd0wmdeanlee
andauthored
CameraView: sync pbo with glFence instead of calling glFinish (#23409)
* CameraView: sync pbo with glFence instead of calling glFinish (#23293) * Sync pbo with fence * use std::unique_ptr * cameraview.cc: call glFlush after creating fence Co-authored-by: Dean Lee <[email protected]>
1 parent c4b36ce commit d77782e

File tree

2 files changed

+41
-20
lines changed

2 files changed

+41
-20
lines changed

selfdrive/ui/qt/widgets/cameraview.cc

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

selfdrive/ui/qt/widgets/cameraview.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,20 @@ class CameraViewWidget : public QOpenGLWidget, protected QOpenGLFunctions {
3636
virtual void updateFrameMat(int w, int h);
3737
void vipcThread();
3838

39+
struct WaitFence {
40+
WaitFence() { sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); }
41+
~WaitFence() { glDeleteSync(sync); }
42+
void wait() { glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); }
43+
GLsync sync = 0;
44+
};
45+
3946
bool zoomed_view;
40-
std::atomic<int> latest_texture_id = -1;
47+
std::mutex lock;
48+
int latest_texture_id = -1;
4149
GLuint frame_vao, frame_vbo, frame_ibo;
4250
mat4 frame_mat;
4351
std::unique_ptr<EGLImageTexture> texture[UI_BUF_COUNT];
52+
std::unique_ptr<WaitFence> wait_fence;
4453
std::unique_ptr<QOpenGLShaderProgram> program;
4554
QColor bg = QColor("#000000");
4655

@@ -50,7 +59,6 @@ class CameraViewWidget : public QOpenGLWidget, protected QOpenGLFunctions {
5059
std::atomic<VisionStreamType> stream_type;
5160
QThread *vipc_thread = nullptr;
5261

53-
5462
protected slots:
5563
void vipcConnected(VisionIpcClient *vipc_client);
5664
};

0 commit comments

Comments
 (0)