【发布时间】:2021-05-31 02:05:52
【问题描述】:
我有一个名为“ShowVideo”的类对象,它继承自 QOpenGLWidget 和 QOpenGLFunctions。 在“initializeGL()”函数中,我创建了一个工作线程和一个子渲染器对象,在子渲染器对象中,我创建了一个 QOpenGLContext 对象,它使用 QOpenGLWidget 上下文调用 setShareContext 进行纹理共享。
在“ShowVideo”类下,有一个名为“onSceneSwitch”的成员函数(需要多次调用),其中我会先释放所有子渲染器的opengl资源(QOpenGLFramebufferObject、纹理等)(通过调用glDeleteTextures),然后重新创建 opengl 资源(例如,使用 glGenTextures)。
在带有nvidia显卡的Windows系统上,它工作正常(opengl资源已成功释放,纹理对象名称在“glDeteleTextures”之后可以重复使用,即使共享opengl上下文没有被破坏)。
但是在 ubuntu20.04 上使用 mesa 显卡驱动,opengl 资源无法释放。 (如果我使用 glGenTextures 来生成纹理对象,每次调用“onSceneSwitch”时都会得到新的纹理对象 ID,从而导致快速超过“GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS”)
代码示例如下:
class ShowVideo : public QOpenGLWidget,protected QOpenGLFunctions
{
protected:
void initializeGL()
{
m_mainRendererContext = new QOpenGLContext();
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setRedBufferSize(8);
format.setBlueBufferSize(8);
format.setGreenBufferSize(8);
format.setAlphaBufferSize(8);
format.setVersion(2, 0);
format.setProfile(QSurfaceFormat::CoreProfile);
m_mainRendererContext->setFormat(format);
m_mainRendererContext->setShareContext(this->context());
m_mainRendererContext->create();
m_mainRenderThread = new QThread;
m_mainRenderer = new MainRenderer();
m_mainRenderer->moveToThread(m_mainRenderThread);
m_mainRendererContext->moveToThread(m_mainRenderThread);
m_mainRenderer->setGLContext(m_mainRendererContext);
}
void onSceneSwitch()
{
emit m_mainRenderer->releaseGLResourceSignal();
...
emit m_mainRenderer->reCreateGLResourceSignal();
}
};
class MainRenderer : public QObject, protected QOpenGLFunctions
{
private:
GLuint m_texUnit;
QOpenGLFramebufferObject *m_Fbo = nullptr;
QOpenGLContext *mContext;
QOffscreenSurface *mSurface
public:
void setGLContext(QOpenGLContext *context)
{
m_Context = context;
}
void releaseGLResource()
{
mContext->makeCurrent(mSurface);
glDeleteTextures(1, &m_texUnit);
delete m_Fbo;
m_Fbo = 0;
}
void reCreateGLResource()
{
mContext->makeCurrent(mSurface);
glGenTextures(1, &m_texUnit);
qDebug() << "the m_texUnit is : " << m_texUnit;
m_Fbo = new QOpenGLFramebufferObject (size, format);
}
}
例如,如果“m_texUnit”在 glGenTextures 之后初始化时为 3,在 Windows 系统上,我每次在“onSceneSwitch”中的 glGenTextures 之后都可以得到 3;但是在ubuntu系统中,因为两个openGLcontext对象是共享的,所以纹理对象名是无法释放的。
顺便说一下,我设置两个openglContext共享的原因是,在类“ShowVideo”的成员函数“paintGL”中,我使用“MainRenderer”中生成的纹理id进行渲染。
【问题讨论】: