Loading...
Searching...
No Matches
HdRenderThread Class Reference

HdRenderThread is a utility that specific render delegates can choose to use depending on their needs. More...

#include <renderThread.h>

Public Member Functions

API for thread management

Methods to configure, start, and stop the render thread. These functions are not threadsafe.

HD_API void SetRenderCallback (std::function< void()> renderCallback)
 Set the rendering callback for the render thread to use.
 
HD_API void SetShutdownCallback (std::function< void()> shutdownCallback)
 Set the shutdown callback for the render thread to use.
 
HD_API void StartThread ()
 Start the rendering background thread.
 
HD_API void StopThread ()
 Stop the rendering background thread.
 
HD_API bool IsThreadRunning ()
 Check whether the background thread is running (i.e.
 
API for hydra threads

Methods for the render thread to communicate with hydra. These should only be called from the render thread, from inside the render callback.

HD_API void StartRender ()
 Ask the render thread to start rendering.
 
HD_API void StopRender ()
 Ask the render thread to stop rendering, and block until the render thread is idle.
 
HD_API bool IsRendering ()
 Query whether the render thread is currently rendering.
 
HD_API void PauseRender ()
 Ask the render thread to pause rendering.
 
HD_API void ResumeRender ()
 Ask the render thread to resume rendering.
 
HD_API bool IsStopRequested ()
 Query whether hydra has asked to interrupt the current frame since the last time StartRender() was called.
 
HD_API bool IsPauseRequested ()
 Query whether hydra has asked to pause rendering.
 
HD_API bool IsPauseDirty ()
 Query whether the pause/resume state has changed since the last time we called IsPauseDirty.
 
API for both hydra and render threads

Methods for both hydra and the render threads to synchronize access to other data.

HD_API std::unique_lock< std::mutex > LockFramebuffer ()
 Return a scoped lock on the render delegate's framebuffer.
 

Detailed Description

HdRenderThread is a utility that specific render delegates can choose to use depending on their needs.

It provides a system for rendering in a background thread, and synchronizing between hydra (either in the main thread, or the sync threadpool) and the rendering thread.

State Machine

The render thread is implemented in terms of a state machine, and hydra requests to the render thread are implemented in terms of transitions on that state machine.

States:

  • StateInitial - indicates the render thread hasn't been started.
  • StateIdle - indicates the render thread is running, but not rendering.
  • StateRendering - indicates the render thread is rendering.
  • StateTerminated - indicates the render thread is shutting down.

Transitions:

Example Usage

class ExampleRenderDelegate : HdRenderDelegate {
public:
ExampleRenderDelegate() {
_renderThread.SetRenderCallback(
std::bind(&ExampleRenderDelegate::_RenderCallback, this));
_renderThread.StartThread();
}
~ExampleRenderDelegate() {
_renderThread.StopThread();
}
private:
void _RenderCallback() {
bool renderComplete = false;
while(!renderComplete) {
// Check if we have been asked to pause.
while(_renderThread.IsPauseRequested()) {
if(_renderThread.IsStopRequested()) {
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
if(_renderThread.IsStopRequested()) {
break;
}
// generate N pixels.
auto lock = _renderThread.LockFramebuffer();
// resolve pixels to shared buffer.
// Set renderComplete = true when finished rendering.
}
}
HdRenderThread _renderThread;
};
class ExampleRenderParam : HdRenderParam {
public:
ExampleRenderParam(HdRenderThread* renderThread, SceneData *scene);
SceneData* AcquireSceneForEdit() {
_renderThread->StopRender();
return _scene;
}
};
class ExamplePrim : HdMesh {
public:
void Sync(...) {
SceneData *scene = renderParam->AcquireSceneForEdit();
...
}
};
class ExampleRenderPass : HdRenderPass {
public:
ExampleRenderPass(HdRenderThread *renderThread);
protected:
void _Execute(...) {
_renderThread->StartRendering();
auto lock = _renderThread->LockFramebuffer();
// blit pixels from shared to application buffer.
}
};
Hydra Schema for a subdivision surface or poly-mesh object.
Definition: mesh.h:113
The HdRenderParam is an opaque (to core Hydra) handle, to an object that is obtained from the render ...
An abstract class representing a single render iteration over a set of prims (the HdRprimCollection),...
Definition: renderPass.h:70
HdRenderThread is a utility that specific render delegates can choose to use depending on their needs...
Definition: renderThread.h:146

Having a locked and shared framebuffer is important if you want to avoid tearing, or if the rendering API disallows multithreaded access to buffers (for example, if your framebuffers are on a GPU). It might be unnecessary for some renderers.

Stopping the render only when you're about to make a scene edit means that long-running renders aren't interrupted if the scene is static. Hiding the renderer's scene data handle behind AcquireSceneForEdit helps callers use the synchronization mechanisms correctly.

The render is restarted at the last possible second, in the render pass, after we know scene edits are done.

The render callback should use IsStopRequested() as a cancellation mechanism.

Definition at line 146 of file renderThread.h.

Member Function Documentation

◆ IsPauseDirty()

HD_API bool IsPauseDirty ( )

Query whether the pause/resume state has changed since the last time we called IsPauseDirty.

◆ IsPauseRequested()

HD_API bool IsPauseRequested ( )

Query whether hydra has asked to pause rendering.

This will continue to return true until a request has been made for rendering to resume. Remember to check for a stop request while paused.

◆ IsRendering()

HD_API bool IsRendering ( )

Query whether the render thread is currently rendering.

This is set by StartRender() and reset after the render callback exits, or reset by StopRender() if the render callback never runs. This does not block, and is fully threadsafe.

◆ IsStopRequested()

HD_API bool IsStopRequested ( )

Query whether hydra has asked to interrupt the current frame since the last time StartRender() was called.

The render callback can check this to determine whether to cancel rendering.

◆ IsThreadRunning()

HD_API bool IsThreadRunning ( )

Check whether the background thread is running (i.e.

StartThread was called successfully, but StopThread has not been).

◆ LockFramebuffer()

HD_API std::unique_lock< std::mutex > LockFramebuffer ( )

Return a scoped lock on the render delegate's framebuffer.

Hydra and the render thread can use this to synchronize blits between render-thread owned resources, and application-owned resources.

◆ PauseRender()

HD_API void PauseRender ( )

Ask the render thread to pause rendering.

The speed at which the renderer actually enters the pause state depends on the delegate.

◆ ResumeRender()

HD_API void ResumeRender ( )

Ask the render thread to resume rendering.

Pause and Resume calls do not need to be paired. The last call (to Pause or Resume) decides the current state.

◆ SetRenderCallback()

HD_API void SetRenderCallback ( std::function< void()>  renderCallback)

Set the rendering callback for the render thread to use.

◆ SetShutdownCallback()

HD_API void SetShutdownCallback ( std::function< void()>  shutdownCallback)

Set the shutdown callback for the render thread to use.

This will be called once, right before the render thread exits, regardless of whether the render callback has been called. This can be used to clean up thread-specific rendering resources.

◆ StartRender()

HD_API void StartRender ( )

Ask the render thread to start rendering.

This call is a no-op if the render thread is already rendering. Otherwise, it may block briefly. This is threadsafe against the render thread, but it shouldn't be called at the same time as StopRender(), and it shouldn't be called from multiple hydra threads at once.

◆ StartThread()

HD_API void StartThread ( )

Start the rendering background thread.

Note: it's an error to call this function when the render thread is already running, but it's acceptable to stop the render thread and then start it again.

◆ StopRender()

HD_API void StopRender ( )

Ask the render thread to stop rendering, and block until the render thread is idle.

This is fully threadsafe, and can be called from multiple hydra threads at once.

◆ StopThread()

HD_API void StopThread ( )

Stop the rendering background thread.

This function will ask the render thread to transition to StateTerminated, and then join on the thread, so it will block. After this function returns, the rendering state machine will be back in its initial state, and the render thread can be started again.


The documentation for this class was generated from the following file: