Win32 Message Pump和std :: thread用于创建OpenGL上下文和渲染

时间:2015-06-13 01:30:04

标签: multithreading winapi opengl c++11

如果我有一个执行以下操作的功能:

bool foo::init()
{
    [Code that creates window]
    std::thread run(std::bind(&foo::run, this));

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

其中run定义为:

void foo::run()
{
    [Code that creates initial opengl context]
    [Code that recreates window based on new PixelFormat using wglChoosePixelFormatARB]
    [Code that creates new opengl context using wglCreateContextAttribsARB]

    do {
        [Code that handles rendering]
    } while (!terminate);   
}

由于窗口是在渲染线程上重新创建的,并且消息泵将在主线程上执行,这被认为是安全的吗? WndProc会被调用什么功能?上面的代码可能被认为是糟糕的设计,但这不是我感兴趣的。我只对定义的行为感兴趣。

1 个答案:

答案 0 :(得分:2)

Win32窗口绑定到创建它的线程。 该线程可以接收和分发窗口的消息,而该线程可以破坏窗口。

因此,如果您在工作线程内部重新创建窗口,那么该线程必须承担管理窗口和分发其消息的责任。

否则,您需要将窗口的重新创建委托给主线程,以便它保留在最初创建它的同一个线程中。

bool foo::init()
{
    [Code that creates window]

    std::thread run(std::bind(&foo::run, this));

    while (GetMessage(&msg, NULL, 0, 0)) {
        if (recreate needed) {
            [Code that recreates window and signals worker thread]
            continue;
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

void foo::run()
{
    [Code that creates initial opengl context]

    [Code that asks main thread to recreate window based on new PixelFormat using wglChoosePixelFormatARB, and waits for signal that the recreate is finished]

    [Code that creates new opengl context using wglCreateContextAttribsARB]

    do {
        [Code that handles rendering]
    } while (!terminate);   
}

否则,在启动工作线程之前在主线程中调用wglChoosePixelFormatARB(),并将所选的PixelFormat存储在线程可以访问它的位置。

bool foo::init()
{
    [Code that creates window]
    [Code that gets PixelFormat using wglChoosePixelFormatARB]

    std::thread run(std::bind(&foo::run, this));

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

void foo::run()
{
    [Code that creates opengl context using wglCreateContextAttribsARB]

    do {
        [Code that handles rendering]
    } while (!terminate);   
}