Qt/OpenGL:我正确使用PBO吗?
Qt/OpenGL : Am I using PBO correctly ?
我正在做一个项目,用OpenGL显示视频流,然后在外部屏幕上显示QOpenGLWidget
上的内容。所以我所做的是在OpenGL小部件上显示流,然后我使用glReadPixels
和两个像素包缓冲对象来获取缓冲区并将其发送到另一个屏幕。问题是,与不使用pbo相比,使用pbo时我的性能会下降。
创建将发送到外部屏幕的帧的代码:
screenBuffer
是存储来自QOpenGLWidget
的帧的内存缓冲区
paintGL
函数
中的数据填充了。void GLWidget::videodisplay(unsigned char *copy){
update();
unsigned char* frame = publicCreateOutputVideoFrame();
if(pboIndex){
pbo1->bind();
pbo1->read(0, screenBuffer, vWidth*vHeight*3);
}else{
pbo2->bind();
pbo2->read(0, screenBuffer, vWidth*vHeight*3);
}
pboIndex = !pboIndex;
unsigned char* yuvFrame = convertRGBtoYUV(screenBuffer);
memcpy(frame, yuvFrame, vWidth*vHeight*2);
publicDisplayVideoFrameSync();
delete yuvFrame;
yuvFrame = NULL;
delete copy;
copy = NULL;
}
初始化PBO:
void GLWidget::InitializeGL(){
pbo1 = new QOpenGLBuffer(QOpenGLBuffer::PixelPackBuffer);
pbo1->create();
pbo1->bind();
pbo1->allocate(vWidth*vHeight*3);
pbo1->release();
pbo2 = new QOpenGLBuffer(QOpenGLBuffer::PixelPackBuffer);
pbo2->create();
pbo2->bind();
pbo2->allocate(vWidth*vHeight*3);
pbo2->release();
}
这里我使用PBO和glReadPixels
void GLWidget::paintGL(){
glClear(GL_COLOR_BUFFER_BIT);
program->bind();
{
vao.bind();
glBindTexture(GL_TEXTURE_2D, tex);
glDrawArrays(GL_QUADS, 0, 4);
glBindTexture(GL_TEXTURE_2D, 0);
vao.release();
}
program->release();
if(!isZoomed){
programMouse->bind();
{
vaoMouse.bind();
glLineWidth(2.0);
glDrawArrays(GL_LINES, 0, 8);
vaoMouse.release();
}
programMouse->release();
}
if(pboIndex){
pbo2->bind();
}else{
pbo1->bind();
}
glReadPixels(0, 0, vWidth, vHeight, GL_RGB, GL_UNSIGNED_BYTE, 0);
if(pboIndex){
pbo2->release();
}else{
pbo1->release();
}
}
pboIndex
只是一个布尔值,用于在第一个和第二个PBO之间切换值。
显然,因为我的性能下降,我做错了什么?我使用pbo的方式不对,或者我没有正确理解我应该使用它们的情况。
谢谢
您对像素缓冲对象背后的目的有一个大致的了解(我认为),通过两个不同缓冲区之间的每帧乒乓来演示。真正的问题是两个像素缓冲区可能不足以防止管道停滞。
许多驱动程序都被配置为为三个帧排队命令,如果你试图在n+2
帧期间读回n
帧的结果,你就有效地缩短了最大管道深度。n+2
帧的命令设置将不允许继续,直到n
的结果完成并被读取。
驱动程序的命令排队行为远远超出了OpenGL的范围,你将永远无法知道驱动程序设置了多少帧来提前工作。将读回之间的时间长度增加到3会有所帮助,但理想情况下,您希望使用栅栏同步。
你可以在OpenGL的命令流中插入一个同步对象,它的唯一目的是在所有命令完成到某一点时发出信号。检查该对象的信号状态不会以任何方式停止管道,并允许您快速判断前一帧的命令何时在GPU上完成,并且像素缓冲区的回读不会引入任何CPU/GPU同步问题。
相关文章:
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 了解 GLM- openGL 中的相机转换
- 如何在全屏模式下(在OpenGL中)使背景透明
- 为什么我不能使用 EGL 创建无头 OpenGl 上下文?
- OpenGL大的3D纹理(>2GB)非常慢
- OpenGl glm rotate
- C++atioglxx.pdb未加载错误glBufferData OpenGL
- OpenGL在启用深度测试时不会丢弃我的碎片
- OpenGL相机和相机空间转型的困惑
- OpenGL将纹理四边形渲染为(0,0)
- OpenGL 和 GLM 矩阵无法正确扩展,总是按比例缩小
- 发布旋转矩阵(openGL/glm)
- 如何在Visual Basic中使用矩形函数OpenGL绘制矩形
- 具有PBO的GPU视频流在OpenGL中加载ImageQT
- openGL PBO 使用 wglcontext,而不是创建窗口
- OpenGL PBO和纹理对象:我需要为两者分配内存吗
- 有没有人有PBO + SDL2.0 + OpenGL的例子
- Qt/OpenGL:我正确使用PBO吗?
- 需要OpenGL/PBO像素绘制示例
- 如何将PBO与Qt OpenGL结合使用