From 688b55c8e02a9ecc2ec37c5193f6fb24a2d33ff4 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Wed, 17 Nov 2021 19:01:50 +0800 Subject: [PATCH] ui: async uploading texture with PBO (#22843) * async uploading texture using pbo * use QOpenglBuffer space set usage pattern share context continue * space old-commit-hash: 0dcb089254df1addd20c031f131086632302184f --- selfdrive/ui/qt/widgets/cameraview.cc | 58 +++++++++++++++++++++++---- selfdrive/ui/qt/widgets/cameraview.h | 2 + 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/selfdrive/ui/qt/widgets/cameraview.cc b/selfdrive/ui/qt/widgets/cameraview.cc index 19eb4ab770..1daabd7d1e 100644 --- a/selfdrive/ui/qt/widgets/cameraview.cc +++ b/selfdrive/ui/qt/widgets/cameraview.cc @@ -1,5 +1,8 @@ #include "selfdrive/ui/qt/widgets/cameraview.h" +#include +#include + namespace { const char frame_vertex_shader[] = @@ -197,18 +200,13 @@ void CameraViewWidget::paintGL() { 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); - if (!Hardware::EON()) { - // this is handled in ion on QCOM - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, latest_frame->width, latest_frame->height, - GL_RGB, GL_UNSIGNED_BYTE, latest_frame->addr); - } glUseProgram(program->programId()); glUniform1i(program->uniformLocation("uTexture"), 0); @@ -251,6 +249,25 @@ void CameraViewWidget::vipcThread() { VisionStreamType cur_stream_type = stream_type; std::unique_ptr vipc_client; + std::unique_ptr ctx; + std::unique_ptr surface; + std::unique_ptr gl_buffer; + + if (!Hardware::EON()) { + ctx = std::make_unique(); + ctx->setFormat(context()->format()); + ctx->setShareContext(context()); + ctx->create(); + assert(ctx->isValid()); + + surface = std::make_unique(); + surface->setFormat(ctx->format()); + surface->create(); + ctx->makeCurrent(surface.get()); + assert(QOpenGLContext::currentContext() == ctx.get()); + initializeOpenGLFunctions(); + } + while (!QThread::currentThread()->isInterruptionRequested()) { if (!vipc_client || cur_stream_type != stream_type) { cur_stream_type = stream_type; @@ -262,11 +279,38 @@ void CameraViewWidget::vipcThread() { QThread::msleep(100); continue; } + + if (!Hardware::EON()) { + 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()); } if (VisionBuf *buf = vipc_client->recv(nullptr, 1000)) { - emit vipcThreadFrameReceived(buf); + 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(); + + // copy pixels from PBO to texture object + glBindTexture(GL_TEXTURE_2D, texture[buf->idx]->frame_tex); + 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); + } } } } diff --git a/selfdrive/ui/qt/widgets/cameraview.h b/selfdrive/ui/qt/widgets/cameraview.h index caf686cee8..90622c6b77 100644 --- a/selfdrive/ui/qt/widgets/cameraview.h +++ b/selfdrive/ui/qt/widgets/cameraview.h @@ -48,6 +48,8 @@ protected: std::atomic stream_type; QThread *vipc_thread = nullptr; + std::mutex texture_lock; + protected slots: void vipcConnected(VisionIpcClient *vipc_client); void vipcFrameReceived(VisionBuf *buf);