Fidchells_eye's picture

Multi-threading problem: Context is Null, How?

Hi,
I'm working on making our GL scopes multi-threaded with OpenTK.
The unit-test program has no problems. Now when used in one of our products, I get the GraphicsContextMissingException() exception, and trying to find the spot where it triggers, and what causes it.
The designed has the vertex data compiled in another thread and sent to the main to be rendered.

Thank you for your time and answers,
Fidchells_eye


Comments

Comment viewing options

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

There is too little information to understand what is happening.

  • Which version of OpenTK?
  • What operating system?
  • What GPU?
  • What drivers?
  • Do you have a stacktrace?

The only reasonable advice would be to read the documentation for GraphicsContext and use apitrace to record a trace of OpenGL calls and find the cause of the error.

Fidchells_eye's picture

OpenTK 1.0
Win 7 pro
Nvidia Geforce 550
Latest Drivers

Stack Trace (How do you do that?)

Will be Looking through the GraphicsContext and using apitrace to record the trace of GL Calls.

the Fiddler's picture

You can retrieve the stack trace using the GraphicsContextMissingException.StackTrace property.

The most likely cause for GraphicsContextMissingException is that you are issuing OpenGL commands on a thread that does not have an OpenGL context (GraphicsContext). This is not allowed and will results in undefined behavior.

An OpenGL context can only be current on a single thread. By default, this is the thread that owns the GLControl or GameWindow. You can call MakeCurrent to move a context to a different thread, but if you do this, you will no longer be able to issue OpenGL commands one the original thread.

You can create more than one GraphicsContext if necessary. This is subject to many limitations. Refer to the OpenGL specification, section 2.1 for more information.

Edit: I would suggest moving to OpenTK 1.1 if at all possible. OpenTK 1.0 has a bug that will cause it to crash on some Win8 systems.

Fidchells_eye's picture

The threads only fill in a VBO, of vertex and Color arrays. I have no GL commands in the data_preparation threads. Only the Main thread has the GL commands.

And What should I look for in a API trace, trace file.
I do see a spot where it goes null, but then goes to context = 0x10001.

I'll upgrade the OpenTK and see if that helps

Fidchells_eye's picture

Installed 1.1, now get on unit test project.

Error
Code:270
Description: The command "..\..\Binaries\OpenTK\Debug\..\..\Tools\Debug\Rewrite.exe ..\..\Binaries\OpenTK\Debug\OpenTK.dll ..\..\OpenTK.snk -debug" exited with code 3.
D:\Documents\OpenTK\1.1\Source\OpenTK\OpenTK.csproj
Line: 820
Column: 5
Project: OpenTK

the Fiddler's picture

OpenTK 1.1 uses a two-step compilation. First, OpenTK.dll is compiled by the csharp compiler, then Rewrite.exe is executed to weave the OpenGL bindings. Windows error 3 is "path not found", i.e. Rewrite.exe was not found on the expected path "Binaries\Tools\Debug".

You may need to adjust your build system to build the "Generator.Rewrite" project first.

This is normally done automatically by OpenTK.sln:

msbuild OpenTK.sln /p:Configuration=Debug
Fidchells_eye's picture

Thank you that fixed that problem.

Moving on to the threading Unit-test then I'll test with with the Product and see if the context problem goes away.

Edit: Nope Context still goes null somewhere.

the Fiddler's picture
Quote:

Edit: Nope Context still goes null somewhere.

This is almost certainly an application error.

The debug version of OpenTK checks that a context is available before issuing an OpenGL call. The code essentially boils down to this:

public class GL
{
    public static void FooBar()
    {
        if (GraphicsContext.CurrentContext == null)
            throw new GraphicsContextMissingException();
 
       // call FooBar
 
       if (GL.GetError() != ErrorCode.NoError)
           throw new GraphicsException();
    }
}

GraphicsContext.CurrentContext retrieves the OpenGL context for the current thread. The fact that you are seeing an exception here indicates one of three things:

  1. You are calling an OpenGL function before creating a GLControl or GameWindow
  2. You are calling an OpenGL function from a thread that does not have a current OpenGL context (e.g. from a thread-pool thread)
  3. You are creating your own OpenGL context (either with wglCreateContext or via a 3rd-party library) without informing OpenTK about its existence (via
    new GraphicsContext(your_context_handle))</li>
    </ol>
     
    A stack trace will give you the exact location of the crash (your unit testing framework should be able to give you stack traces.)
     
    Apitrace will give you the exact sequence of calls that led to this error. You will immediately see if an OpenGL call was made before the creation of the context or on a thread without a current context. In fact, it could be extremely useful to integrate apitrace into your unit test suite - this way, whenever a test fails you will get the complete sequence of OpenGL calls that led to that failure. (I certainly know that I will be doing that in all my projects in the future.)