Skip to content

Commit 0a241c1

Browse files
committed
[hdEmbree] ensure we respect PXR_WORK_THREAD_LIMIT
1 parent 7341bf0 commit 0a241c1

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

pxr/imaging/plugin/hdEmbree/renderer.cpp

+74
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,77 @@
2222
#include <chrono>
2323
#include <thread>
2424

25+
// -------------------------------------------------------------------------
26+
// Old TBB workaround - can remove once OneTBB is mandatory
27+
// -------------------------------------------------------------------------
28+
#include <tbb/tbb_stddef.h>
29+
30+
#if TBB_INTERFACE_VERSION_MAJOR < 12
31+
32+
#include <memory>
33+
34+
#include <tbb/task_scheduler_init.h>
35+
36+
PXR_NAMESPACE_OPEN_SCOPE
37+
38+
extern TfEnvSetting<int> PXR_WORK_THREAD_LIMIT;
39+
40+
PXR_NAMESPACE_CLOSE_SCOPE
41+
42+
namespace {
43+
44+
PXR_NAMESPACE_USING_DIRECTIVE
45+
46+
// This function always returns either 0 (meaning "no change") or >= 1
47+
//
48+
// Duplication of code from threadLimits.cpp - copied here to avoid having to
49+
// change API of work lib. Will go away once we don't need to support tbb < 12
50+
// (ie, pre-OneTBB)
51+
static unsigned
52+
HdEmbree_NormalizeThreadCount(const int n)
53+
{
54+
// Zero means "no change", and n >= 1 means exactly n threads, so simply
55+
// pass those values through unchanged.
56+
// For negative integers, subtract the absolute value from the total number
57+
// of available cores (denoting all but n cores). If |n| >= number of cores,
58+
// clamp to 1 to set single-threaded mode.
59+
return n >= 0 ? n : std::max<int>(1, n + WorkGetPhysicalConcurrencyLimit());
60+
}
61+
62+
63+
// Returns the normalized thread limit value from the environment setting. Note
64+
// that 0 means "no change", i.e. the environment setting does not apply.
65+
//
66+
// Duplication of code from threadLimits.cpp - copied here to avoid having to
67+
// change API of work lib. Will go away once we don't need to support tbb < 12
68+
// (ie, pre-OneTBB)
69+
static unsigned
70+
HdEmbree_GetConcurrencyLimitSetting()
71+
{
72+
return HdEmbree_NormalizeThreadCount(TfGetEnvSetting(PXR_WORK_THREAD_LIMIT));
73+
}
74+
75+
76+
// Make the calling context respect PXR_WORK_THREAD_LIMIT, if run from a thread
77+
// other than the main thread (ie, the renderThread)
78+
class _ScopedThreadScheduler {
79+
public:
80+
_ScopedThreadScheduler() {
81+
auto limit = HdEmbree_GetConcurrencyLimitSetting();
82+
if (limit != 0) {
83+
_tbbTaskSchedInit =
84+
std::make_unique<tbb::task_scheduler_init>(limit);
85+
}
86+
}
87+
88+
std::unique_ptr<tbb::task_scheduler_init> _tbbTaskSchedInit;
89+
};
90+
91+
} // anonymous namespace
92+
93+
#endif // TBB_INTERFACE_VERSION_MAJOR < 12
94+
95+
2596
namespace {
2697

2798
PXR_NAMESPACE_USING_DIRECTIVE
@@ -453,6 +524,9 @@ HdEmbreeRenderer::Render(HdRenderThread *renderThread)
453524

454525
// Render by scheduling square tiles of the sample buffer in a parallel
455526
// for loop.
527+
#if TBB_INTERFACE_VERSION_MAJOR < 12
528+
_ScopedThreadScheduler scheduler;
529+
#endif
456530
// Always pass the renderThread to _RenderTiles to allow the first frame
457531
// to be interrupted.
458532
WorkParallelForN(numTilesX*numTilesY,

0 commit comments

Comments
 (0)