This document is for a version of USD that is under development. See this page for the current release.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
renderThread.h
1//
2// Copyright 2018 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_IMAGING_HD_RENDER_THREAD_H
8#define PXR_IMAGING_HD_RENDER_THREAD_H
9
10#include "pxr/pxr.h"
11#include "pxr/imaging/hd/api.h"
12
13#include <atomic>
14#include <condition_variable>
15#include <functional>
16#include <mutex>
17#include <thread>
18
19PXR_NAMESPACE_OPEN_SCOPE
20
21
130public:
131
132 HD_API
134
135 HD_API
137
145
147 HD_API
148 void SetRenderCallback(std::function<void()> renderCallback);
149
154 HD_API
155 void SetShutdownCallback(std::function<void()> shutdownCallback);
156
161 HD_API
163
169 HD_API
171
174 HD_API
176
178
186
192 HD_API
194
198 HD_API
200
205 HD_API
207
210 HD_API
212
216 HD_API
218
220
228
232 HD_API
234
238 HD_API
240
243 HD_API
245
247
255
259 HD_API
260 std::unique_lock<std::mutex> LockFramebuffer();
261
263
264private:
265 // _RenderLoop implements the render thread's state machine; see
266 // \ref HdRenderThread_StateMachine for details. It runs in a background
267 // thread and manages synchronization with hydra. To implement rendering,
268 // it calls out to the render callback provided via SetRenderCallback.
269 void _RenderLoop();
270
271 // _renderCallback is the render-delegate-provided function responsible for
272 // actually rendering. It's called from _RenderLoop.
273 std::function<void()> _renderCallback;
274
275 // _shutdownCallback is the render-delegate-provided function responsible
276 // for cleaning up thread-specific resources. It's called once, right
277 // before _RenderLoop exits.
278 std::function<void()> _shutdownCallback;
279
280 // A placeholder initial value for _renderCallback.
281 static void _DefaultRenderCallback();
282
283 // A placeholder initial value for _shutdownCallback.
284 static void _DefaultShutdownCallback();
285
286 // The state enumeration of the render thread state machine; see
287 // \ref HdRenderThread_StateMachine for details.
288 enum State {
289 // Initial constructed state. Render thread is not running.
290 StateInitial,
291 // Render thread is running and ready for scene edits. No rendering
292 // is taking place.
293 StateIdle,
294 // Render thread is running and rendering; no scene edits are allowed.
295 StateRendering,
296 // Render thread is shutting down.
297 StateTerminated,
298 };
299
300 // _requestedState is set by hydra to direct the render thread's state
301 // machine; see \ref HdRenderThread_StateMachine for details.
302 // _requestedState is protected by a mutex/condition variable combination.
303 // The render thread holds _requestedStateMutex while rendering; the
304 // frequency with which it can give it up is the interruption frequency.
305 //
306 // StartRender() and StopRender() lock and write to _requestedState.
307 // _RenderLoop() locks and reads _requestedState.
308 State _requestedState;
309 std::mutex _requestedStateMutex;
310 std::condition_variable _requestedStateCV;
311
312 // _enableRender provides an out-of-band way for hydra to cancel a
313 // render while the render thread is still holding _requestedStateMutex.
314 //
315 // StartRender() and StopRender() will write true/false to _enableRender.
316 // IsStopRequested() will read from _enableRender.
317 std::atomic_flag _enableRender;
318 // _stopRequested keeps track of whether _enableRender has gone low since
319 // the last time the render callback was called (since _enableRender is
320 // reset on read).
321 bool _stopRequested;
322
323 // _pauseRender provides a properly locked boolean flag that holds the
324 // current pause state of the thread. Toggled by calling PauseRender and
325 // ResumeRender, tested by IsPauseRequested.
326 std::atomic<bool> _pauseRender;
327
328 // _pauseDirty provides a properly locked boolean flag that holds the
329 // current dirtyness of the pause state of the thread. Toggled by
330 // calling PauseRender and ResumeRender, tested by IsPauseDirty.
331 std::atomic<bool> _pauseDirty;
332
333 // _rendering records whether the render thread is currently inside the
334 // render callback, or planning to be inside the render callback.
335 // It is managed by StartRender(), StopRender(), and _RenderLoop().
336 // IsRendering() will read from _rendering.
337 std::atomic<bool> _rendering;
338
339 // _renderThread is the background render thread; it runs _RenderLoop().
340 std::thread _renderThread;
341
342 // _frameBufferMutex protects access to the render delegate's framebuffer,
343 // and provides an optional synchronization point for blits between the
344 // render thread's resources and the application's resources.
345 std::mutex _frameBufferMutex;
346};
347
348
349PXR_NAMESPACE_CLOSE_SCOPE
350
351#endif // PXR_IMAGING_HD_RENDER_THREAD_H
HdRenderThread is a utility that specific render delegates can choose to use depending on their needs...
Definition: renderThread.h:129
HD_API void StopThread()
Stop the rendering background thread.
HD_API void StartRender()
Ask the render thread to start rendering.
HD_API bool IsPauseDirty()
Query whether the pause/resume state has changed since the last time we called IsPauseDirty.
HD_API bool IsPauseRequested()
Query whether hydra has asked to pause rendering.
HD_API bool IsThreadRunning()
Check whether the background thread is running (i.e.
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 std::unique_lock< std::mutex > LockFramebuffer()
Return a scoped lock on the render delegate's framebuffer.
HD_API void PauseRender()
Ask the render thread to pause rendering.
HD_API bool IsRendering()
Query whether the render thread is currently rendering.
HD_API void SetRenderCallback(std::function< void()> renderCallback)
Set the rendering callback for the render thread to use.
HD_API bool IsStopRequested()
Query whether hydra has asked to interrupt the current frame since the last time StartRender() was ca...
HD_API void ResumeRender()
Ask the render thread to resume rendering.
HD_API void StopRender()
Ask the render thread to stop rendering, and block until the render thread is idle.