GLFW has long delay when creating a window


#1

I’m using GLFW for the first time. Pulled the latest stable release (3.2.1) and I’m using the example code found on the GLFW website:

#include <GLFW/glfw3.h>

int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

There’s a fairly long delay (20 seconds or so) on the call to choosePixelFormat() (wgl_context.c) - nativeCount has a value of 627 and it seems to just take a long time in the for loop.

There’s no delay if I use freeGLUT to create a window or if I just create a window directly with WinAPI calls (CreateWindow, etc) and set up the PFD myself.

I’m using Windows 10, tried it first with Visual Studio 2015 and then in 2017. Graphics card is NVidia Quadro M6000.

I did slightly modify the above code to add a call to initialize glew, but having this call or not did not change the delay.


#2

That’s a ridiculously long time. Can you get more detailed information on what inside of choosePixelFormat is taking so long and whether it’s on the first iteration or across them all?


#3

Hi Elmindreda. I apologize about not responding - we ended up just sticking with the Win32 API directly, but we’re back at a point where we want to use GLFW for our project and I wanted to revisit this because it’s still occurring.

I timed it out to 13 seconds from the moment I start the application to when the window appears. The bulk of that time is spent inside choosePixelFormat() in wgl-context.c, iterating through that loop. The loop counter is checked against the value nativeCount, which for me is 672. It doesn’t appear to hang on any particular iteration, at least not the first ten.

When the loop does end, I end up with a usableCount of 180 for what it’s worth.

While running through the loop, _glfw.wgl.ARB_pixel_format conditional always returns true. It does seem odd, because a loop of 672 doesn’t seem like it should take 13 seconds to process. I have to assume it’s getting caught up in one of the other function calls inside that loop (getPixelFormatAttrib), but I’m not sure on which iteration it would be.


#4

A few things to check:

  • If you start a Release build of an unaltered example without debugging (Visual Studio->Start Without Debugging) does the window take as long to create?
  • Windows 10 April 2018 update introduced a long delay to apps when going full screen due to “Focus assist”. This shouldn’t happen for most examples and your first report was before this but do check: Windows key—>Configuration(the gear)—>System—>Focus Assist—>DISABLE everything!.
  • It’s worth doing a graphics driver update just to check this isn’t the problem.

#5

Hi Doug, thanks for the reply.

  1. I built the project in Release configuration and ran without debugging, no change. Even running the executable directly outside of VS has no impact.

  2. I could not find a Focus Assist setting anywhere. Perhaps I’m on an older version of Windows 10? Mycompany is slow at releasing these updates.

  3. Unfortunately I think my company restricts updating our drivers on our work laptops. Right now we’re using NVidia Quadro M2000M, and the driver version says 21.21.13.6949. My NVidia control panel says Version 369.49.


#6

It looks like 369.49 was released in Oct 2016. https://www.nvidia.com/download/driverResults.aspx/108579/en-us.

To view your Windows Version number in Start Menu type “system information” and click that. The version number for the April 2018 release is Build 17134 https://en.wikipedia.org/wiki/Windows_10_version_history#Version_1803_(April_2018_Update).

Have you tried running the same executable on a machine not from your work with recent Windows and driver? This may help narrow down the issue.

The large amount of time spent makes me think there is something very different with your system to anything I’m used to seeing.

On my machine if I run a profile in Visual Studio (Analyze->Performance Profiler select CPU) I can drill down into glfwPlatformCreateWIndow (which takes 250ms) to see ChoosePixelFormat takes 174ms. Debugging shows that the nativeCount is 467, and the loop uses the _glfw.wgl.ARB_pixel_format branch of the conditional with a usableCount of 180. You have around 1.5x more pixel formats, but 13 seconds is almost 100 times slower so there’s something odd here.


#7

Quick thought:

ChoosePixelFormat calls getPixelFormatAttrib around 20x per loop. This in turn calls wglGetPixelFormatAttribivARB which could be slow on your system for some reason.

Calling wglGetPixelFormatAttribivARB once for all required attributes might improve performance if this is the case by up to 20x, which could get you within reasonable performance times for your setup.

If you’re willing to help test this I could look into doing some work on this area.


#8
  1. Windows version: Microsoft Windows 10 Enterprise, 10.0.16299

  2. I can try testing on a similar machine later today

  3. Right now we’re using Visual Studio Express 2015, but they recently purchased a 2017 Professional license for me so I will run a performance profiler on it as soon as I can.

  4. I’m absolutely willing to test this, let me know what you need me to do. Thanks!


#9

Quick update: I just ran the same executable on another machine that has NVidia drivers 148.92 and the window opened immediately. So it’s certainly something specific to my laptop.


#10

As I started looking into this work I noted that the profile I was looking at had ChoosePixelFormat taking 174ms but this was the WIN32 API ChoosePixelFormat. The GLFW function choosePixelFormat was only taking 2ms.

I have a version of the glfw choosePixelFormat which uses only one call to wglGetPixelFormatAttribivARB per format on:

If you pull that array-based-choosePixelFormat (it’s based off master branch so as to make a pull request easier if this works out for you) it might help with your issue, in which case we should raise an issue on Github then I can clean up the code ready for a pull request to GLFW.


#11

Here’s one more thing to look into: https://hero.handmade.network/forums/code-discussion/t/2503-[day_235]_opengls_pixel_format_takes_a_long_time#12672

Some time ago I’ve debugged into nvidia GL implementation to figure out why it takes so long to create GL context. Turns out it was looping all over the game profile settings. Reducing profile list to smaller (by taking from older driver) helped significantly. Still it was in hundreds of msec range, not multiple seconds.


#12

Right - if the time is being spent in ChoosePixelFormat (capital letter start) then this is purely driver related.

If the time is being spent in choosePixelFormat this is GLFW code and whilst the likely problem may be the driver my commit might lower this slightly.


#13

Hello - I tried it again with the changes you provided. There’s a noticeable improvement, it’s down to 4-5 seconds before the window launches. Thank you for the help.


#14

Apologies for the delay.

I’ve submitted a pull request as below, though due to the additional complexity I’m unsure if this it is a wise decision to add to the codebase (you may want to chime in if it’s very useful to you).


#15

These changes have now been merged into the master branch of GLFW and should arrive in version 3.3.