-
Notifications
You must be signed in to change notification settings - Fork 36
Multithreading using contexts
When loading large amount of data in the main thread there will be a large amount of stutters. Therefore it is benefical to use several threads. There is just one issue: Graphics API object can't be simply shared across multiple threads. That's where context come to use: After you bind a context everything loaded afterwards will belong to that context. Without a context bound the engine wouldn't work. That's why every engine instance object has a context it can access. This context is bound by default. You can test the effects of the context yourself by unbinding it:
void App::LoadContent() {
...
context.Unbind();
...
}The result is lots of errors and a black screen if not even worse. Every context is associated with a window. The window won't work without a context and the context wouldn't work without a window. That's why you need to attach a context to every new window you create. You also need to attach a window to every context if you want to use that context.
void App::LoadContent() {
...
Atlas::Window otherWindow = ...
context.AttachTo(&otherWindow);
...
}Note: For the default window the context available by the instance is already attached.
A context can only be attached to one window in one thread at a time. That means if you would wan't to draw in two windows simultaneously you need two contexts.
When you want to use several threads and share data between threads you need the same number of context as there are threads. Contexts only shares data with other contexts if the contexts were created in the same thread.
Warning: All data of a context becomes inaccessible to the graphics API if the context is destructed.
There is one more interesting thing to note: If contexts are in different threads they can use the same window.
void SomeThread(Atlas::Context* context) {
context->Bind();
...
context->Unbind();
}
void App::LoadContent() {
...
Atlas::Context otherThreadContext;
otherThreadContext.AttachTo(&window);
context.Bind();
...
// Start thread somehow
...
}As you can see we have to bind the default context again. That's because when you attach a context to a window it is automatically bound in the current thread.
Note: Not all engine objects will be shared across multiple context. Here is a list of all the classes which don't support it:
- Meshes (but MeshData is supported)
- RenderTargets
As you can see it is fairly easy to use multithreading. Don't hesitate to use that feature, it might make your application less CPU bound.