Skip to content

Commit 8cd783b

Browse files
committed
Implement vectorized HdMergingSceneIndex::RemoveInputScenes()
1 parent 1ffb188 commit 8cd783b

File tree

2 files changed

+57
-37
lines changed

2 files changed

+57
-37
lines changed

pxr/imaging/hd/mergingSceneIndex.cpp

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -253,59 +253,76 @@ HdMergingSceneIndex::RemoveInputScenes(
253253
{
254254
TRACE_FUNCTION();
255255

256-
// Vectorization not implemented yet :(
256+
if (sceneIndices.empty()) {
257+
return;
258+
}
257259

260+
// Remove our observer from the scene indices being removed.
261+
HdSceneIndexObserverPtr observerPtr(&_observer);
258262
for (const HdSceneIndexBaseRefPtr &sceneIndex : sceneIndices) {
259-
RemoveInputScene(sceneIndex);
263+
sceneIndex->RemoveObserver(observerPtr);
260264
}
261-
}
262265

263-
void
264-
HdMergingSceneIndex::RemoveInputScene(const HdSceneIndexBaseRefPtr &sceneIndex)
265-
{
266-
TRACE_FUNCTION();
266+
// Remove the scene indices from our list of inputs, and record a list of
267+
// their scene roots for generating the added/removed notifications below.
268+
std::vector<_InputEntry> removedInputs;
269+
{
270+
std::unordered_set<HdSceneIndexBaseRefPtr, TfHash> sceneIndicesSet;
271+
sceneIndicesSet.insert(sceneIndices.begin(), sceneIndices.end());
267272

268-
auto it = std::find_if(
269-
_inputs.begin(), _inputs.end(),
270-
[&sceneIndex](const _InputEntry &entry) {
271-
return sceneIndex == entry.sceneIndex; });
273+
auto it = std::stable_partition(
274+
_inputs.begin(), _inputs.end(),
275+
[&sceneIndicesSet](const _InputEntry &entry) {
276+
return !sceneIndicesSet.count(entry.sceneIndex);
277+
});
272278

273-
if (it == _inputs.end()) {
274-
return;
279+
removedInputs.assign(it, _inputs.end());
280+
_inputs.erase(it, _inputs.end());
275281
}
276282

277-
std::vector<SdfPath> removalTestQueue = { it->sceneRoot };
278-
279-
sceneIndex->RemoveObserver(HdSceneIndexObserverPtr(&_observer));
280-
_inputs.erase(it);
281283
_RebuildInputsPathTable();
282284

283285
if (!_IsObserved()) {
284286
return;
285287
}
286288

287-
// prims unique to this input get removed
289+
// prims unique to these inputs get removed
288290
HdSceneIndexObserver::RemovedPrimEntries removedEntries;
289291

290-
// prims which this input contributed to are resynced via
292+
// prims which these inputs contributed to are resynced via
291293
// PrimsAdded.
292294
HdSceneIndexObserver::AddedPrimEntries addedEntries;
293295

294-
// signal removal for anything not present once this scene is
295-
// removed
296-
while (!removalTestQueue.empty()) {
297-
const SdfPath path = removalTestQueue.back();
298-
removalTestQueue.pop_back();
296+
// Set to prevent sending duplicate notifications.
297+
std::unordered_set<SdfPath, SdfPath::Hash> visitedPaths;
299298

300-
const HdSceneIndexPrim prim = GetPrim(path);
301-
if (!prim.dataSource
302-
&& GetChildPrimPaths(path).empty()) {
303-
removedEntries.emplace_back(path);
304-
} else {
305-
addedEntries.emplace_back(path, prim.primType);
306-
for (const SdfPath &childPath :
307-
sceneIndex->GetChildPrimPaths(path)) {
308-
removalTestQueue.push_back(childPath);
299+
std::vector<SdfPath> removalTestQueue;
300+
for (const _InputEntry &removedInput : removedInputs) {
301+
// signal removal for anything not present once this scene is
302+
// removed
303+
removalTestQueue.push_back(removedInput.sceneRoot);
304+
305+
while (!removalTestQueue.empty()) {
306+
const SdfPath path = removalTestQueue.back();
307+
removalTestQueue.pop_back();
308+
309+
auto [_, notVisited] = visitedPaths.insert(path);
310+
311+
const HdSceneIndexPrim prim = GetPrim(path);
312+
if (!prim.dataSource
313+
&& GetChildPrimPaths(path).empty()) {
314+
if (notVisited) {
315+
removedEntries.emplace_back(path);
316+
}
317+
} else {
318+
if (notVisited) {
319+
addedEntries.emplace_back(path, prim.primType);
320+
}
321+
322+
for (const SdfPath &childPath :
323+
removedInput.sceneIndex->GetChildPrimPaths(path)) {
324+
removalTestQueue.push_back(childPath);
325+
}
309326
}
310327
}
311328
}
@@ -318,6 +335,12 @@ HdMergingSceneIndex::RemoveInputScene(const HdSceneIndexBaseRefPtr &sceneIndex)
318335
}
319336
}
320337

338+
void
339+
HdMergingSceneIndex::RemoveInputScene(const HdSceneIndexBaseRefPtr &sceneIndex)
340+
{
341+
RemoveInputScenes({sceneIndex});
342+
}
343+
321344
std::vector<HdSceneIndexBaseRefPtr>
322345
HdMergingSceneIndex::GetInputScenes() const
323346
{

pxr/imaging/hd/testenv/testHdMergingSceneIndex.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,13 +259,10 @@ _TestRemoveInputScenes()
259259
return _CompareValue(
260260
"NOTICES", logEntries,
261261
{
262-
_LogEntry("remove", "/A/B/C/D/E"),
262+
_LogEntry("remove", "/A/B/C/D"),
263263
_LogEntry("remove", "/A/B/C/D2"),
264264
_LogEntry("add", "/A/B"),
265265
_LogEntry("add", "/A/B/C"),
266-
_LogEntry("add", "/A/B/C/D"),
267-
_LogEntry("remove", "/A/B/C/D"),
268-
_LogEntry("add", "/A/B/C"),
269266
});
270267
}
271268

0 commit comments

Comments
 (0)