Loading...
Searching...
No Matches
renderThread.h
1//
2// Copyright 2018 Pixar
3//
4// Licensed under the Apache License, Version 2.0 (the "Apache License")
5// with the following modification; you may not use this file except in
6// compliance with the Apache License and the following modification to it:
7// Section 6. Trademarks. is deleted and replaced with:
8//
9// 6. Trademarks. This License does not grant permission to use the trade
10// names, trademarks, service marks, or product names of the Licensor
11// and its affiliates, except as required to comply with Section 4(c) of
12// the License and to reproduce the content of the NOTICE file.
13//
14// You may obtain a copy of the Apache License at
15//
16// http://www.apache.org/licenses/LICENSE-2.0
17//
18// Unless required by applicable law or agreed to in writing, software
19// distributed under the Apache License with the above modification is
20// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21// KIND, either express or implied. See the Apache License for the specific
22// language governing permissions and limitations under the Apache License.
23//
24#ifndef PXR_IMAGING_HD_RENDER_THREAD_H
25#define PXR_IMAGING_HD_RENDER_THREAD_H
26
27#include "pxr/pxr.h"
28#include "pxr/imaging/hd/api.h"
29
30#include <atomic>
31#include <condition_variable>
32#include <functional>
33#include <mutex>
34#include <thread>
35
36PXR_NAMESPACE_OPEN_SCOPE
37
38
147public:
148
149 HD_API
151
152 HD_API
154
162
164 HD_API
165 void SetRenderCallback(std::function<void()> renderCallback);
166
171 HD_API
172 void SetShutdownCallback(std::function<void()> shutdownCallback);
173
178 HD_API
180
186 HD_API
188
191 HD_API
193
195
203
209 HD_API
211
215 HD_API
217
222 HD_API
224
227 HD_API
229
233 HD_API
235
237
245
249 HD_API
251
255 HD_API
257
260 HD_API
262
264
272
276 HD_API
277 std::unique_lock<std::mutex> LockFramebuffer();
278
280
281private:
282 // _RenderLoop implements the render thread's state machine; see
283 // \ref HdRenderThread_StateMachine for details. It runs in a background
284 // thread and manages synchronization with hydra. To implement rendering,
285 // it calls out to the render callback provided via SetRenderCallback.
286 void _RenderLoop();
287
288 // _renderCallback is the render-delegate-provided function responsible for
289 // actually rendering. It's called from _RenderLoop.
290 std::function<void()> _renderCallback;
291
292 // _shutdownCallback is the render-delegate-provided function responsible
293 // for cleaning up thread-specific resources. It's called once, right
294 // before _RenderLoop exits.
295 std::function<void()> _shutdownCallback;
296
297 // A placeholder initial value for _renderCallback.
298 static void _DefaultRenderCallback();
299
300 // A placeholder initial value for _shutdownCallback.
301 static void _DefaultShutdownCallback();
302
303 // The state enumeration of the render thread state machine; see
304 // \ref HdRenderThread_StateMachine for details.
305 enum State {
306 // Initial constructed state. Render thread is not running.
307 StateInitial,
308 // Render thread is running and ready for scene edits. No rendering
309 // is taking place.
310 StateIdle,
311 // Render thread is running and rendering; no scene edits are allowed.
312 StateRendering,
313 // Render thread is shutting down.
314 StateTerminated,
315 };
316
317 // _requestedState is set by hydra to direct the render thread's state
318 // machine; see \ref HdRenderThread_StateMachine for details.
319 // _requestedState is protected by a mutex/condition variable combination.
320 // The render thread holds _requestedStateMutex while rendering; the
321 // frequency with which it can give it up is the interruption frequency.
322 //
323 // StartRender() and StopRender() lock and write to _requestedState.
324 // _RenderLoop() locks and reads _requestedState.
325 State _requestedState;
326 std::mutex _requestedStateMutex;
327 std::condition_variable _requestedStateCV;
328
329 // _enableRender provides an out-of-band way for hydra to cancel a
330 // render while the render thread is still holding _requestedStateMutex.
331 //
332 // StartRender() and StopRender() will write true/false to _enableRender.
333 // IsStopRequested() will read from _enableRender.
334 std::atomic_flag _enableRender;
335 // _stopRequested keeps track of whether _enableRender has gone low since
336 // the last time the render callback was called (since _enableRender is
337 // reset on read).
338 bool _stopRequested;
339
340 // _pauseRender provides a properly locked boolean flag that holds the
341 // current pause state of the thread. Toggled by calling PauseRender and
342 // ResumeRender, tested by IsPauseRequested.
343 std::atomic<bool> _pauseRender;
344
345 // _pauseDirty provides a properly locked boolean flag that holds the
346 // current dirtyness of the pause state of the thread. Toggled by
347 // calling PauseRender and ResumeRender, tested by IsPauseDirty.
348 std::atomic<bool> _pauseDirty;
349
350 // _rendering records whether the render thread is currently inside the
351 // render callback, or planning to be inside the render callback.
352 // It is managed by StartRender(), StopRender(), and _RenderLoop().
353 // IsRendering() will read from _rendering.
354 std::atomic<bool> _rendering;
355
356 // _renderThread is the background render thread; it runs _RenderLoop().
357 std::thread _renderThread;
358
359 // _frameBufferMutex protects access to the render delegate's framebuffer,
360 // and provides an optional synchronization point for blits between the
361 // render thread's resources and the application's resources.
362 std::mutex _frameBufferMutex;
363};
364
365
366PXR_NAMESPACE_CLOSE_SCOPE
367
368#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:146
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.