Skip to content

Commit 89e974f

Browse files
committed
[hdEmbree] ensure we respect PXR_WORK_THREAD_LIMIT
1 parent 7341bf0 commit 89e974f

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

pxr/imaging/plugin/hdEmbree/renderer.cpp

+84
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,87 @@
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+
// PXR_WORK_THREAD_LIMIT isn't exported as part of it's api, and we're not
39+
// part of the work library, so we can't use:
40+
// extern TfEnvSetting<int> PXR_WORK_THREAD_LIMIT;
41+
extern std::variant<int, bool, std::string> const *
42+
Tf_GetEnvSettingByName(std::string const&);
43+
44+
PXR_NAMESPACE_CLOSE_SCOPE
45+
46+
namespace {
47+
48+
PXR_NAMESPACE_USING_DIRECTIVE
49+
50+
// This function always returns either 0 (meaning "no change") or >= 1
51+
//
52+
// Duplication of code from threadLimits.cpp - copied here to avoid having to
53+
// change API of work lib. Will go away once we don't need to support tbb < 12
54+
// (ie, pre-OneTBB)
55+
static unsigned
56+
HdEmbree_NormalizeThreadCount(const int n)
57+
{
58+
// Zero means "no change", and n >= 1 means exactly n threads, so simply
59+
// pass those values through unchanged.
60+
// For negative integers, subtract the absolute value from the total number
61+
// of available cores (denoting all but n cores). If |n| >= number of cores,
62+
// clamp to 1 to set single-threaded mode.
63+
return n >= 0 ? n : std::max<int>(1, n + WorkGetPhysicalConcurrencyLimit());
64+
}
65+
66+
67+
// Returns the normalized thread limit value from the environment setting. Note
68+
// that 0 means "no change", i.e. the environment setting does not apply.
69+
//
70+
// Duplication of code from threadLimits.cpp - copied here to avoid having to
71+
// change API of work lib. Will go away once we don't need to support tbb < 12
72+
// (ie, pre-OneTBB)
73+
static unsigned
74+
HdEmbree_GetConcurrencyLimitSetting()
75+
{
76+
std::variant<int, bool, std::string> const *
77+
variantValue = Tf_GetEnvSettingByName("PXR_WORK_THREAD_LIMIT");
78+
int threadLimit = 0;
79+
if (int const *value = std::get_if<int>(variantValue)) {
80+
threadLimit = *value;
81+
}
82+
return HdEmbree_NormalizeThreadCount(threadLimit);
83+
}
84+
85+
86+
// Make the calling context respect PXR_WORK_THREAD_LIMIT, if run from a thread
87+
// other than the main thread (ie, the renderThread)
88+
class _ScopedThreadScheduler {
89+
public:
90+
_ScopedThreadScheduler() {
91+
auto limit = HdEmbree_GetConcurrencyLimitSetting();
92+
if (limit != 0) {
93+
_tbbTaskSchedInit =
94+
std::make_unique<tbb::task_scheduler_init>(limit);
95+
}
96+
}
97+
98+
std::unique_ptr<tbb::task_scheduler_init> _tbbTaskSchedInit;
99+
};
100+
101+
} // anonymous namespace
102+
103+
#endif // TBB_INTERFACE_VERSION_MAJOR < 12
104+
105+
25106
namespace {
26107

27108
PXR_NAMESPACE_USING_DIRECTIVE
@@ -453,6 +534,9 @@ HdEmbreeRenderer::Render(HdRenderThread *renderThread)
453534

454535
// Render by scheduling square tiles of the sample buffer in a parallel
455536
// for loop.
537+
#if TBB_INTERFACE_VERSION_MAJOR < 12
538+
_ScopedThreadScheduler scheduler;
539+
#endif
456540
// Always pass the renderThread to _RenderTiles to allow the first frame
457541
// to be interrupted.
458542
WorkParallelForN(numTilesX*numTilesY,

0 commit comments

Comments
 (0)