1
\$\begingroup\$

PeekMessage, TranslateMessage, and DispatchMessage often take a long time (sometimes more than a millisecond for a single message). Is this normal? How do people deal with this? I thought about handling messages on a separate thread, but that would introduce unnecessary complexity and wouldn't really solve the problem.

Here's what my game loop looks like:

int WINAPI WinMain(...)
{
    // ...
    
    bool running = true;
    while( running )
    {
        running = poll_messages();
        update();
        render();
        SwapBuffers( whatever );
    }
    
    // ...
}
    
bool poll_messages()
{
    bool keep_running = true;
    MSG msg;
    while( PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE) )
    {
        TranslateMessage( &msg );
        DispatchMessageA( &msg );

        if( msg.message == WM_QUIT )
            keep_running = false;
    }
    
    return keep_running;
}

And part of the window proc:

LRESULT CALLBACK wnd_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
    LRESULT result = 0;

    switch( msg )
    {
        // ...
        
        // I removed most cases, but here's one of the most frequent offenders.
        // pretty much all the time is spent in GetRawInputData when handling this message.
        case WM_INPUT:
        {
            BYTE data[ sizeof(RAWINPUT) ];
            UINT data_size = furo_arr_cnt(data);
            UINT bytes_written = GetRawInputData( HRAWINPUT(lparam), RID_INPUT, data, &data_size, sizeof(RAWINPUTHEADER) );
            if( bytes_written == data_size )
            {
                RAWINPUT* raw_input = (RAWINPUT*)data;
                if( raw_input->header.dwType == RIM_TYPEMOUSE &&
                    raw_input->data.mouse.usFlags == MOUSE_MOVE_RELATIVE )
                {
                    int x_relative = raw_input->data.mouse.lLastX;
                    int y_relative = raw_input->data.mouse.lLastY;

                    // convert from screen space to OpenGL viewport space
                    y_relative = -y_relative;

                    platform_raw_mouse_delta_event( x_relative, y_relative );
                }
            }
            else
                log_err( "failed to get raw mouse input (ec=%u)", GetLastError() );

            break;
        }
        
        // ...

        default:
            result = DefWindowProcA( hwnd, msg, wparam, lparam );
            break;
    }

    return result;
}
\$\endgroup\$
1
  • \$\begingroup\$ In one case, yes, but there are other messages that take a long time. That's just one example. Sometimes even TranslateMessage takes a long time. \$\endgroup\$ Commented Oct 12, 2022 at 18:22

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.