mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-06-30 19:12:07 +08:00
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
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
#include "selfdrive/ui/qt/widgets/cameraview.h"
|
||||
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOffscreenSurface>
|
||||
|
||||
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<VisionIpcClient> vipc_client;
|
||||
|
||||
std::unique_ptr<QOpenGLContext> ctx;
|
||||
std::unique_ptr<QOffscreenSurface> surface;
|
||||
std::unique_ptr<QOpenGLBuffer> gl_buffer;
|
||||
|
||||
if (!Hardware::EON()) {
|
||||
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()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ protected:
|
||||
std::atomic<VisionStreamType> stream_type;
|
||||
QThread *vipc_thread = nullptr;
|
||||
|
||||
std::mutex texture_lock;
|
||||
|
||||
protected slots:
|
||||
void vipcConnected(VisionIpcClient *vipc_client);
|
||||
void vipcFrameReceived(VisionBuf *buf);
|
||||
|
||||
Reference in New Issue
Block a user