winterhell's picture

[solved] Switching windows focus slowdowns with GameWindow

Hi.
When I'm running an application with GameWindow and try to switch to another window I get a couple of seconds OS interface pause before the other window shows. The same thing happens when trying to get back to the GameWindow application, or minimizing/restoring it. It is more apparent when navigating with the taskbar rather than clicking on the actual window(which is impossible if you want Visual Studio/etc to be maximized). Also when starting the application it shows halfway on the taskbar and only after several seconds shows fully.

The problem is there on at least OpenTK 1.0 and 1.1 Beta 3, including the samples themselves.

I'm running Windows 7 64bit, GeForce GTX 650( on 660 Ti its the same), Visual Studio 2010.
Is this fixable?

If not, I'm willing to switch to GLControl, but would that compromise the portability to Linux and OS X?

Thanks.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

Can you please report an issue at https://github.com/opentk/opentk/issues?

Please include information on which drivers you are using. You can get this through the "OpenGL Diagnostics" sample or via glview. OpenGL Diagnostics gives you something like:

Renderer: Intel(R) HD Graphics 2000
GL Version: 3.1.0 - Build 9.17.10.3223
MajorVersion: 3
MinorVersion: 1
GLSL Version: 1.40 - Intel Build 9.17.10.3223

I am not getting this on any of my systems (loading, changing windows, etc is instantaneous), but I have seen reports of trouble with Nvidia in the past. This should be fixable.

You can determine if GLControl works any better by running the "GLControl Game Loop" sample in the example browser. GLControl runs on Linux and Mac OS X, but the result is definitely subpar on those platforms.

Edit: this has previously been reported here at http://www.opentk.com/node/2479

the Fiddler's picture

Can you please try the SDL2 backend?

Using 1.1-beta3, copy SDL2.dll from Dependencies/x86 or Dependencies/x64 to the application folder and re-run the application. Does it behave the same?

winterhell's picture

Edit:

Yes when I copied the dll to the output folder it worked. Thanks.

the Fiddler's picture

Ok, this means it's something specific to the way OpenTK initializes OpenGL. Which means this is fixable, if we can find out the exact cause.

winterhell's picture

So I tested the build I had against 1.0. On Windows XP GeForce 4 MX (latest drivers are years old) the problem persists. Taskbar lag when it starts, and lags when switching away or minimizing. This time switching back to and restoring the window work as they should.

On my VMWare neither Windows 98 or Ubuntu 12 have the problem. On probably unrelated issue, virtual OS X crashes with BadPixelFormat from OpenTK.Platform.MacOS.AglContext.CreateContext(... ). I'm guessing its the lack of 3D acceleration or something, because on a real iMac it run(cant remember if it had the same switching issue as on Windows).

It looks like the Window messages stack is being clogged. When I try to repeat the task before it is happened(minimize maximize etc) it does all actions at once after the lag.
I'm targeting .Net 2.0 if that makes any difference.

the Fiddler's picture

This is certainly a windows-specific issue. So far it has only been observed on Nvidia GPUs. I have never encountered it myself, but it appears to be recurring.

If you are willing to run a few tests, I would really appreciate your help to get to the bottom of this. I've setup a branch specifically to address this issue but there are a few things to test first:

  1. Is "threaded optimization" turned on in the Nvidia Control Panel? Does anything change if you toggle this setting?
  2. What is the driver version on the systems that display this issue? Nvidia has made major changes to their OpenGL drivers after 265.xx and 290.xx, if I remember correctly, which might affect this issue.
  3. Is the issue reproducible using the wgl_issue19 branch? I've encountered some trouble with Nvidia, when gdi32.dll and opengl32.dll are loaded dynamically in the same process. This branch routes all setup code through opengl32/wgl which might make a difference.
  4. If you run the process through a profiler for a few seconds, which functions take up most of the time?

If the pattern I've seen so far holds, the profiler will show that wglGetProcAddress and wglMakeCurrent take an abnormal amount of time to return. This, in turn, causes window messages to pile up, leading to the lag behavior you are observing.

The question is to understand why this is happening and find a way to avoid it.

Edit: the codepaths for wgl, glx, agl, sdl2 are completely different. This issue is specific to the wgl codepath.

The windows/wgl codepath in OpenTK does two slightly uncommon things, compared to most other toolkits (sdl, glfw, glut, etc): first, it uses a message filter to read mouse/keyboard input messages so it can receive messages even if the window is not focused; second, it constructs the OpenGL context not on a top-level window, but on a child window parented to a top-level window. The reason for this is to work around visual corruption that is visible on AMD cards when toggling WindowBorder from Normal to Hidden (low-level programming is fun, isn't it.)

I do not believe these differences are the cause here but that can only be proven by testing.

winterhell's picture

1. Threaded optimizations has little to no effect on this.

2. Currently the drivers are 331.65 from last month and 93.81 from 2006.
The issue occured with at least 4 different WHQL drivers(and possibly some betas) from this year, among them 310.90 and 314.22. Be warned though, some of the drivers after 314.22 tend to brick GPUs out of the blue.
I haven't noticed if the issue was present with last years drivers.

3. When I tried the release of this branch, in the Example window output:

Exception occured in example Examples.Tutorial.SimpleWindow: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> OpenTK.Graphics.GraphicsContextException: Context creation failed. Wgl.CreateContext() error: 2000.
   at OpenTK.Platform.Windows.WinGLContext..ctor(GraphicsMode format, WinWindowInfo window, IGraphicsContext sharedContext, Int32 major, Int32 minor, GraphicsContextFlags flags) in E:\opentk-wgl_issue19\opentk-wgl_issue19\Source\OpenTK\Platform\Windows\WinGLContext.cs:line 175

Btw the context menu Copy in the Output window does not change the clipboard. At least Ctrl+C works.

4. Running through SlimTune didnt show anything meaningfull, most of the time is spent in the regular Game1.OnRenderFrame,even though I cleared the results and spammed the lag events for 15 seconds.

Yeah I found OpenTK to be very robust with handling the input even at thousands of fps and have a great overall performance.

the Fiddler's picture

Thanks for testing, this has uncovered something. Searching for error 2000 brings up the following: http://stackoverflow.com/questions/199016/wglcreatecontext-in-c-sharp-fa...

Quote:

Somwhere on the internet I found that when you are linking opengl32.lib while compiling c++ application it must be placed before gdi32.lib. The reason for this is that (supposedly) opengl32.dll is overwriting ChoosePixelFormat and SetPixelFormat functions (and probably more :-).

There is a high chance that OpenTK is loading gdi32 before opengl32, which might be corrupting the vtables of the dlls. It currently works (or appears to work) because we are combining calls to wgl and gdi, e.g. wglDescribePixelFormat with gdi SetPixelFormat. Documentation on this topic is quite hard to come by, but there is a chance that the "error 2000" you are getting is somehow linked with the lag issue (I am not getting this error on my test systems, which also do not exhibit lag.)

Correlation does not imply causation, of course, but let's put this to the test. I'll spin a patch against the wgl_issue19 branch in a moment.

the Fiddler's picture

Ok, patch committed: https://github.com/opentk/opentk/commit/dd31b41f08ced4860cb06d4d87189b97...

This moves the call to LoadLibrary("opengl32.dll") as early in the startup sequence as possible. Can you please check whether this makes any difference?

winterhell's picture

No luck, same issue.
I also tried the GLControl forms, they get .Net Framework Error form with"Content creation failed. Wgl.CreateContext() error:2000".
If I click Continue it talks about possible corrupted memory and then starts the form with the GLControl being unavalable crossed with an X.