Home -> Threading Model

Threading Model

The Cobalt Renderer API has some thread safety guarantees, however it does not offer complete thread safety for all operations in all circumstances. As a guiding rule, a given object should only be built on one thread, or have its modifications externally synchronized. IE, don't create an ITextureBuffer2D and call SetInitialData on one thread, then call AllocateMemory on another. In this case, you would need to externally synchronize. When following this guidance, operations are thread safe, with the following notable exceptions:

Despite the threading rules given above, there is one important synchronization rule within the scope of a single renderer. The StartNewFrame method must be called in complete exclusion to all other calls on that renderer and all objects created from it. No other renderer API call in that object tree should be in progress when StartNewFrame is called, and no other call should begin until it returns. This allows the renderer to latch a coherent frame boundary efficiently. Synchronization helpers to make this rule easier to follow are described below.

Window System Calls

Native window systems often impose their own threading requirements. Calls that bind or resize platform windows, such as BindWindow and NotifyWindowResized, must be made on the UI thread required by the active platform or window framework. The exact UI-thread dispatch mechanism is application-specific.

These calls still belong to the renderer object tree. If they can occur while another thread is advancing frames, they must be synchronized with StartNewFrame in the same way as other renderer calls.

Synchronization Helpers

To assist with synchronization requirements, the ReadWriteMutex helper class provides a reference implementation of a mutex that allows multiple concurrent readers and a single exclusive writer. Pending write lock attempts take priority over later read lock requests, which helps a render thread acquire the exclusive frame-advance lock without being starved by update threads.

Applications are free to use a different locking scheme. If the application design guarantees that no renderer API calls can overlap StartNewFrame, no additional external synchronization is required.

Next page, Allocation Model