X由于应用程序(使用C++、Qt、OpenGL)而挂起
X hangs up because of application (use C++, Qt, OpenGL)
我的应用程序从网络中获取数据并在场景中绘制(场景使用手工制作的OpenGL引擎)。
它能工作几个小时。当我不使用桌面时,由于显示器电源管理器信号(dpms),我的显示器会关闭。然后,当我触摸鼠标或键盘时,显示器会打开,应用程序也会挂断(X也会挂起)。
如果我这样做xset -dmps
操作系统不使用dpms,应用程序运行稳定。
这些问题发生在Centos 6和Archlinux中,但当我在Ubuntu 12.10下运行应用程序时,它运行得很好!
我尝试了不同的NVidia驱动程序。没有效果。
我尝试使用ssh远程登录,并使用gdb连接到进程。监视器打开后,我在进程表中找不到应用程序。
如何诊断问题?当监视器关闭/打开时(在OpengGL环境中)会发生什么?Ubuntu在使用dpms时会做一些特别的事情吗?
我们对问题的原因有一个猜测!当监视器关闭时,我们将丢失OpenGL上下文。当监视器唤醒时,应用程序将挂起(没有上下文)。不同操作系统的行为差异是因为不同的显示器连接:Kubuntu的显示器使用VGA电缆连接。因此(可能)它对X的行为没有影响。
您是否尝试过使用GL_ARB_robustness为OpenGL实现添加健壮性支持?
2.6"图形重置恢复"
某些事件可能导致GL上下文的重置。这样的重置导致所有上下文状态丢失。从此类事件中恢复需要重新创建受影响上下文中的所有对象。这个返回图形重置状态的当前状态
enum GetGraphicsResetStatusARB();
返回的符号常量指示GL上下文是否已在自上次调用以来的任何时间点的重置状态GetGraphicsResetStatusARB。NO_ERROR表示总账上下文具有自上次调用以来未处于重置状态。GUILTY_CONTEXT_RESET_ARB表示检测到重置可归因于当前GL上下文。无辜_文本_设置_ ARB表示检测到不可归因于当前总账上下文。UNKNOWN_CONTEXT_RESET_ARB表示检测到原因未知的图形重置。
此外,在初始化上下文时,请确保您有一个调试上下文,并使用ARB_debug_output扩展来接收日志输出。
void DebugMessageControlARB(enum source,
enum type,
enum severity,
sizei count,
const uint* ids,
boolean enabled);
void DebugMessageInsertARB(enum source,
enum type,
uint id,
enum severity,
sizei length,
const char* buf);
void DebugMessageCallbackARB(DEBUGPROCARB callback,
const void* userParam);
uint GetDebugMessageLogARB(uint count,
sizei bufSize,
enum* sources,
enum* types,
uint* ids,
enum* severities,
sizei* lengths,
char* messageLog);
void GetPointerv(enum pname,
void** params);
例如:
// Initialize GL_ARB_debug_output ASAP
if (glfwExtensionSupported("GL_ARB_debug_output"))
{
typedef void APIENTRY (*glDebugMessageCallbackARBFunc)
(GLDEBUGPROCARB callback, const void* userParam);
typedef void APIENTRY (*glDebugMessageControlARBFunc)
(GLenum source, GLenum type, GLenum severity,
GLsizei count, const GLuint* ids, GLboolean enabled);
auto glDebugMessageCallbackARB = (glDebugMessageCallbackARBFunc)
glfwGetProcAddress("glDebugMessageCallbackARB");
auto glDebugMessageControlARB = (glDebugMessageControlARBFunc)
glfwGetProcAddress("glDebugMessageControlARB");
glDebugMessageCallbackARB(debugCallback, this);
glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE,
GL_DEBUG_SEVERITY_LOW_ARB, 0, nullptr, GL_TRUE);
}
std::string GlfwThread::severityString(GLenum severity)
{
switch (severity)
{
case GL_DEBUG_SEVERITY_LOW_ARB: return "LOW";
case GL_DEBUG_SEVERITY_MEDIUM_ARB: return "MEDIUM";
case GL_DEBUG_SEVERITY_HIGH_ARB: return "HIGH";
default: return "??";
}
}
std::string GlfwThread::sourceString(GLenum source)
{
switch (source)
{
case GL_DEBUG_SOURCE_API_ARB: return "API";
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: return "SYSTEM";
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: return "SHADER_COMPILER";
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: return "THIRD_PARTY";
case GL_DEBUG_SOURCE_APPLICATION_ARB: return "APPLICATION";
case GL_DEBUG_SOURCE_OTHER_ARB: return "OTHER";
default: return "???";
}
}
std::string GlfwThread::typeString(GLenum type)
{
switch (type)
{
case GL_DEBUG_TYPE_ERROR_ARB: return "ERROR";
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: return "DEPRECATED_BEHAVIOR";
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: return "UNDEFINED_BEHAVIOR";
case GL_DEBUG_TYPE_PORTABILITY_ARB: return "PORTABILITY";
case GL_DEBUG_TYPE_PERFORMANCE_ARB: return "PERFORMANCE";
case GL_DEBUG_TYPE_OTHER_ARB: return "OTHER";
default: return "???";
}
}
// Note: this is static, it is called from OpenGL
void GlfwThread::debugCallback(GLenum source, GLenum type,
GLuint id, GLenum severity,
GLsizei, const GLchar *message,
const GLvoid *)
{
std::cout << "source=" << sourceString(source) <<
" type=" << typeString(type) <<
" id=" << id <<
" severity=" << severityString(severity) <<
" message=" << message <<
std::endl;
AssertBreak(type != GL_DEBUG_TYPE_ERROR_ARB);
}
几乎可以肯定,在一个不错的OpenGL实现中,这两个扩展都是可用的。他们帮助很大。调试上下文对所有内容进行验证,并向日志报告。在某些OpenGL实现中,它们甚至在日志输出中给出性能建议。使用ARB_debug_output使检查glGetError
变得过时——它会为您检查每个调用。
您可以从查看X的日志开始,这些日志通常位于/var/log/和~/.xsession错误。OpenGL正在做一些奇怪的事情,这不是不可能的,所以如果你的应用程序有任何日志记录,请打开它。通过运行ulimit -c unlimited
启用核心转储。你可以通过在gdb中打开它来分析转储,如下所示:
gdb <executable file> <core dump file>
看看这是否会产生有用的东西,然后研究它。
- Qt OpenGL 渲染到纹理性能问题
- QT Opengl 总是给黑屏
- 不再使用 QT OpenGL?
- 异步渲染到 Qt OpenGL 窗口
- OpenGL代码在GLFW上工作,但在QT OpenGL上不起作用
- Qt OpenGL帧缓冲在一台PC上创建,但在另一台PC上失败
- 在Linux Mint上编译Qt-OpenGL功能测试失败
- Qt OpengL-旋转三维固定场景
- qt openGL - 球体变形
- Qt OpenGL with Widgets:怎么了?
- Qt OpenGL - 纹理透明度问题
- 将 gDEBugger 与 Qt OpenGL 应用程序结合使用
- Qt OpenGL DrawElements not Drawing the second triangle
- Qt OpenGL 错误'_imp_gl...'
- 获取鼠标坐标Qt OpenGL
- Qt opengl调试SIGSEGV如何修复
- 在QT OpenGL中处理事件
- From Glut and Glew to Qt opengl?
- 使用Qt OpenGL进行文本剪切
- QT OpenGL内存泄漏