【问题标题】:Thread for loading graphics content加载图形内容的线程
【发布时间】:2013-04-17 09:10:16
【问题描述】:

我正在创建游戏引擎。在 Windows 上,我有两个线程和两个共享的上下文(使用 wglShareLists)。它工作得很好。当一个线程加载资源时,另一个线程正在渲染简单的加载屏幕。 在 Linux 上没有 WGL,只有 glX。我不知道如何正确使用它。目前我的线程代码如下所示:

LinuxThread::LinuxThread() :
    handle_(0),
    running_(false),
    task_(0),
    useGraphicsContext_(0),
    threadContext_(0),
    threadDrawable_(0),
    dsp_(0)
{
}

LinuxThread::~LinuxThread() {
    finishTask();
    running_ = false;
    glXDestroyContext(dsp_, threadContext_);
}

ULONG LinuxThread::getId() {
    return static_cast<ULONG>(handle_);
}

void LinuxThread::start() {
    running_ = true;
    pthread_create(&handle_, 0, &LinuxThread::staticRun, (void*) this);
}

bool LinuxThread::isRunning() {
    return running_;
}

void LinuxThread::setGraphicsContext(bool state) {
    if (state) {
        Display* dsp = XOpenDisplay(0);
        threadDrawable_ = glXGetCurrentDrawable();
        GLint att[] = { GLX_RGBA, None };
        XVisualInfo* vi = glXChooseVisual(dsp, 0, att);
        GLXContext glc = glXGetCurrentContext();
        bool directlyToScreen = true; // False for x-server display.
        threadContext_ = glXCreateContext(dsp, vi, glc, directlyToScreen);
    }
    useGraphicsContext_ = state;
}

void LinuxThread::setTask(Task* task) {
//  if (useGraphicsContext_) {
//      task->run();
//      delete task;
//      return;
//  }
    finishTask();
    task_ = task;
}

bool LinuxThread::hasTask() {
    return task_ != 0;
}

void LinuxThread::finishTask() {
    while (task_ != 0) {
        usleep(1000);
    }
}

void LinuxThread::stop() {
    running_ = false;
}

void* LinuxThread::staticRun(void* thread) {
    return (void*) ((LinuxThread*) thread)->run();
}

int LinuxThread::run() {
    while (running_) {
        usleep(10000);
        if (task_ != 0) {
            if (useGraphicsContext_) {
                glXMakeCurrent(dsp_, threadDrawable_, threadContext_);
            }
            task_->run();
            if (useGraphicsContext_) {
                glFinish();
                glXMakeCurrent(dsp_, 0, 0);
            }
            delete task_;
            task_ = 0;
        }
    }
    return 1;
}

它会崩溃并显示如下错误消息:

nouveau: kernel rejected pushbuf: No such file or directory
nouveau: ch6: krec 0 pushes 1 bufs 14 relocs 0
nouveau: ch6: buf 00000000 00000002 00000006 00000006 00000000
nouveau: ch6: buf 00000001 00000010 00000002 00000002 00000000
nouveau: ch6: buf 00000002 0000000f 00000002 00000002 00000002
nouveau: ch6: buf 00000003 0000000e 00000002 00000000 00000002
nouveau: ch6: buf 00000004 00000007 00000002 00000002 00000002
nouveau: ch6: buf 00000005 0000000a 00000002 00000002 00000000
nouveau: ch6: buf 00000006 0000000b 00000002 00000002 00000000

我做错了什么?

【问题讨论】:

  • "在 Windows 上,我有一个带有 OpenGL 上下文的线程。它工作得很好。当一个线程加载资源时,另一个线程正在渲染简单的加载屏幕。" 那不应该“工作美好的”。除非您有两个共享资源的上下文,或者某些系统确保相同的上下文不会同时绑定到两个不同的线程。
  • 我编辑了我的问题。

标签: c++ linux opengl glx


【解决方案1】:

我看不到具体的问题根源,但线程代码使事情复杂化了很多。在你的鞋子里,我会:

  1. 在运行之前尝试设置LIBGL_ALWAYS_SOFTWARE=y,以确保您在新驱动程序中没有遇到问题。 (这将使用内部 Mesa Software 渲染器。)
  2. 将您的共享代码提取到一个线程中,确保它可以工作,然后将已知的工作代码尽可能简单地移回多个线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    相关资源
    最近更新 更多