Skip to content

Commit 5973111

Browse files
unhyperbolicpixar-oss
authored andcommitted
Hydra emulation: making tasks also go through emulation. More precisely, the emulated scene index driven by legacy scene delegates.
This fixes the crash reported in #3471 caused by change 2351061. The problem was that the HdxTaskController added a task without going through emulation. But when we received a removed notice (in this case UsdImagingStageSceneIndex removing /), we removed the task without re-adding it. That is, the merging scene index is removing and re-adding prims. But because the task was not properly emulated, it was never re-added when the merging scene index send the prims added notice. Fixes #3471 (Internal change: 2353415)
1 parent 7579b91 commit 5973111

13 files changed

Lines changed: 281 additions & 21 deletions

pxr/imaging/hd/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pxr_library(hd
5252
dataSource
5353
dataSourceHash
5454
dataSourceLegacyPrim
55+
dataSourceLegacyTaskPrim
5556
dataSourceLocator
5657
dataSourceMaterialNetworkInterface
5758
debugCodes

pxr/imaging/hd/changeTracker.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,26 @@ HdChangeTracker::MarkTaskDirty(SdfPath const& id, HdDirtyBits bits)
401401
return;
402402
}
403403

404+
if (_emulationSceneIndex) {
405+
HdDataSourceLocatorSet locators;
406+
HdDirtyBitsTranslator::TaskDirtyBitsToLocatorSet(
407+
bits, &locators);
408+
if (!locators.IsEmpty()) {
409+
_emulationSceneIndex->DirtyPrims({{id, locators}});
410+
}
411+
} else {
412+
_MarkTaskDirty(id, bits);
413+
}
414+
}
415+
416+
void
417+
HdChangeTracker::_MarkTaskDirty(SdfPath const& id, HdDirtyBits bits)
418+
{
419+
if (ARCH_UNLIKELY(bits == HdChangeTracker::Clean)) {
420+
TF_CODING_ERROR("MarkTaskDirty called with bits == clean!");
421+
return;
422+
}
423+
404424
_IDStateMap::iterator it = _taskState.find(id);
405425
if (!TF_VERIFY(it != _taskState.end(), "Task Id = %s", id.GetText())) {
406426
return;

pxr/imaging/hd/changeTracker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ class HdChangeTracker
670670
void _MarkSprimDirty(SdfPath const& id, HdDirtyBits bits=AllDirty);
671671
void _MarkBprimDirty(SdfPath const& id, HdDirtyBits bits=AllDirty);
672672
void _MarkInstancerDirty(SdfPath const& id, HdDirtyBits bits=AllDirty);
673+
void _MarkTaskDirty(SdfPath const& id, HdDirtyBits bits=AllDirty);
673674
};
674675

675676

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
//
2+
// Copyright 2025 Pixar
3+
//
4+
// Licensed under the terms set forth in the LICENSE.txt file available at
5+
// https://openusd.org/license.
6+
//
7+
#include "pxr/imaging/hd/dataSourceLegacyTaskPrim.h"
8+
9+
#include "pxr/imaging/hd/legacyTaskSchema.h"
10+
#include "pxr/imaging/hd/retainedDataSource.h"
11+
#include "pxr/imaging/hd/sceneDelegate.h"
12+
13+
PXR_NAMESPACE_OPEN_SCOPE
14+
15+
namespace {
16+
17+
class _LegacyTaskSchemaDataSource : public HdContainerDataSource
18+
{
19+
public:
20+
HD_DECLARE_DATASOURCE(_LegacyTaskSchemaDataSource);
21+
22+
TfTokenVector GetNames() override {
23+
static const TfTokenVector result = {
24+
HdLegacyTaskSchemaTokens->factory,
25+
HdLegacyTaskSchemaTokens->parameters,
26+
HdLegacyTaskSchemaTokens->collection,
27+
HdLegacyTaskSchemaTokens->renderTags
28+
};
29+
return result;
30+
}
31+
32+
HdDataSourceBaseHandle Get(const TfToken &name) override {
33+
if (name == HdLegacyTaskSchemaTokens->factory) {
34+
return _ToTypedDataSource(_factory);
35+
}
36+
37+
if (name == HdLegacyTaskSchemaTokens->parameters) {
38+
return HdRetainedSampledDataSource::New(
39+
_sceneDelegate->Get(_id, HdTokens->params));
40+
}
41+
42+
if (name == HdLegacyTaskSchemaTokens->collection) {
43+
return _Get<HdRprimCollection>(HdTokens->collection);
44+
}
45+
46+
if (name == HdLegacyTaskSchemaTokens->renderTags) {
47+
return _Get<TfTokenVector>(HdTokens->renderTags);
48+
}
49+
50+
return nullptr;
51+
}
52+
53+
private:
54+
_LegacyTaskSchemaDataSource(
55+
const SdfPath& id,
56+
HdSceneDelegate * const sceneDelegate,
57+
HdLegacyTaskFactorySharedPtr factory)
58+
: _id(id)
59+
, _sceneDelegate(sceneDelegate)
60+
, _factory(std::move(factory))
61+
{
62+
}
63+
64+
template<typename T>
65+
static
66+
HdDataSourceBaseHandle
67+
_ToTypedDataSource(const T &v)
68+
{
69+
return HdRetainedTypedSampledDataSource<T>::New(v);
70+
}
71+
72+
template<typename T>
73+
HdDataSourceBaseHandle
74+
_Get(const TfToken &key) const {
75+
const VtValue value = _sceneDelegate->Get(_id, key);
76+
if (!value.IsHolding<T>()) {
77+
return nullptr;
78+
}
79+
return _ToTypedDataSource(value.UncheckedGet<T>());
80+
}
81+
82+
const SdfPath _id;
83+
HdSceneDelegate * const _sceneDelegate;
84+
HdLegacyTaskFactorySharedPtr const _factory;
85+
};
86+
87+
}
88+
89+
HdDataSourceLegacyTaskPrim::HdDataSourceLegacyTaskPrim(
90+
const SdfPath& id,
91+
HdSceneDelegate * const sceneDelegate,
92+
HdLegacyTaskFactorySharedPtr factory)
93+
: _id(id)
94+
, _sceneDelegate(sceneDelegate)
95+
, _factory(std::move(factory))
96+
{
97+
}
98+
99+
HdDataSourceLegacyTaskPrim::~HdDataSourceLegacyTaskPrim() = default;
100+
101+
TfTokenVector
102+
HdDataSourceLegacyTaskPrim::GetNames()
103+
{
104+
static const TfTokenVector result = {
105+
HdLegacyTaskSchemaTokens->task
106+
};
107+
return result;
108+
}
109+
110+
HdDataSourceBaseHandle
111+
HdDataSourceLegacyTaskPrim::Get(const TfToken &name)
112+
{
113+
if (!TF_VERIFY(_sceneDelegate)) {
114+
return nullptr;
115+
}
116+
117+
if (name == HdLegacyTaskSchemaTokens->task) {
118+
return _LegacyTaskSchemaDataSource::New(_id, _sceneDelegate, _factory);
119+
}
120+
121+
return nullptr;
122+
}
123+
124+
125+
126+
PXR_NAMESPACE_CLOSE_SCOPE
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//
2+
// Copyright 2025 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_DATA_SOURCE_LEGACY_TASK_PRIM_H
8+
#define PXR_IMAGING_HD_DATA_SOURCE_LEGACY_TASK_PRIM_H
9+
10+
#include "pxr/usd/sdf/path.h"
11+
12+
#include "pxr/imaging/hd/api.h"
13+
#include "pxr/imaging/hd/dataSource.h"
14+
15+
#include "pxr/pxr.h"
16+
17+
PXR_NAMESPACE_OPEN_SCOPE
18+
19+
using HdLegacyTaskFactorySharedPtr = std::shared_ptr<class HdLegacyTaskFactory>;
20+
class HdSceneDelegate;
21+
22+
/// \class HdDataSourceLegacyTaskPrim
23+
///
24+
/// This is an HdContainerDataSource which represents a prim-level data source
25+
/// for a task for adapting HdSceneDelegate calls into the forms defined by
26+
/// HdSchemas during emulation of legacy scene delegates.
27+
///
28+
class HdDataSourceLegacyTaskPrim : public HdContainerDataSource
29+
{
30+
public:
31+
HD_DECLARE_DATASOURCE(HdDataSourceLegacyTaskPrim);
32+
33+
~HdDataSourceLegacyTaskPrim() override;
34+
35+
TfTokenVector GetNames() override;
36+
HdDataSourceBaseHandle Get(const TfToken &name) override;
37+
38+
private:
39+
HdDataSourceLegacyTaskPrim(
40+
const SdfPath& id,
41+
HdSceneDelegate *sceneDelegate,
42+
HdLegacyTaskFactorySharedPtr factory);
43+
44+
const SdfPath _id;
45+
HdSceneDelegate * const _sceneDelegate;
46+
HdLegacyTaskFactorySharedPtr const _factory;
47+
};
48+
49+
HD_DECLARE_DATASOURCE_HANDLES(HdDataSourceLegacyTaskPrim);
50+
51+
PXR_NAMESPACE_CLOSE_SCOPE
52+
53+
#endif

pxr/imaging/hd/dirtyBitsTranslator.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,26 @@ HdDirtyBitsTranslator::BprimDirtyBitsToLocatorSet(TfToken const& primType,
457457
}
458458
}
459459

460+
/* static */
461+
void
462+
HdDirtyBitsTranslator::TaskDirtyBitsToLocatorSet(
463+
const HdDirtyBits bits, HdDataSourceLocatorSet *set)
464+
{
465+
if (ARCH_UNLIKELY(set == nullptr)) {
466+
return;
467+
}
468+
469+
if (bits & HdChangeTracker::DirtyCollection) {
470+
set->append(HdLegacyTaskSchema::GetCollectionLocator());
471+
}
472+
if (bits & HdChangeTracker::DirtyParams) {
473+
set->append(HdLegacyTaskSchema::GetParametersLocator());
474+
}
475+
if (bits & HdChangeTracker::DirtyRenderTags) {
476+
set->append(HdLegacyTaskSchema::GetRenderTagsLocator());
477+
}
478+
}
479+
460480
// ----------------------------------------------------------------------------
461481

462482
static bool

pxr/imaging/hd/dirtyBitsTranslator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ class HdDirtyBitsTranslator
3434
HD_API
3535
static void InstancerDirtyBitsToLocatorSet(TfToken const& primType,
3636
const HdDirtyBits bits, HdDataSourceLocatorSet *set);
37+
HD_API
38+
static void TaskDirtyBitsToLocatorSet(
39+
const HdDirtyBits bits, HdDataSourceLocatorSet *set);
3740

3841
// Locators to dirty bits.
3942
HD_API

pxr/imaging/hd/legacyPrimSceneIndex.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
//
77
#include "pxr/imaging/hd/legacyPrimSceneIndex.h"
88
#include "pxr/imaging/hd/dataSourceLegacyPrim.h"
9+
#include "pxr/imaging/hd/dataSourceLegacyTaskPrim.h"
10+
#include "pxr/imaging/hd/tokens.h"
911
#include "pxr/base/trace/trace.h"
1012

1113
PXR_NAMESPACE_OPEN_SCOPE
@@ -18,6 +20,16 @@ HdLegacyPrimSceneIndex::AddLegacyPrim(SdfPath const &id, TfToken const &type,
1820
HdDataSourceLegacyPrim::New(id, type, sceneDelegate)}});
1921
}
2022

23+
void
24+
HdLegacyPrimSceneIndex::AddLegacyTask(
25+
SdfPath const &id,
26+
HdSceneDelegate * const sceneDelegate,
27+
HdLegacyTaskFactorySharedPtr factory)
28+
{
29+
AddPrims({{id, HdPrimTypeTokens->task,
30+
HdDataSourceLegacyTaskPrim::New(id, sceneDelegate, factory)}});
31+
}
32+
2133
void
2234
HdLegacyPrimSceneIndex::RemovePrim(SdfPath const &id)
2335
{

pxr/imaging/hd/legacyPrimSceneIndex.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
PXR_NAMESPACE_OPEN_SCOPE
1313

1414
class HdSceneDelegate;
15+
using HdLegacyTaskFactorySharedPtr = std::shared_ptr<class HdLegacyTaskFactory>;
1516

1617
TF_DECLARE_REF_PTRS(HdLegacyPrimSceneIndex);
1718

@@ -31,11 +32,18 @@ class HdLegacyPrimSceneIndex : public HdRetainedSceneIndex
3132
return TfCreateRefPtr(new HdLegacyPrimSceneIndex);
3233
}
3334

34-
/// custom insertion wrapper called by HdRenderIndex during population
35-
/// of legacy HdSceneDelegates
35+
/// Custom insertion wrapper called by HdRenderIndex during population
36+
/// of legacy HdSceneDelegate's.
3637
void AddLegacyPrim(SdfPath const &id, TfToken const &type,
3738
HdSceneDelegate *sceneDelegate);
3839

40+
/// Custom insertion wrapper called by HdRenderIndex::InsertTask<T>
41+
/// during population of legacy HdSceneDelegate's
42+
void AddLegacyTask(
43+
SdfPath const &id,
44+
HdSceneDelegate *sceneDelegate,
45+
HdLegacyTaskFactorySharedPtr factory);
46+
3947
/// Remove only the prim at \p id without affecting children.
4048
///
4149
/// If \p id has children, it is replaced by an entry with no type

pxr/imaging/hd/renderIndex.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -600,9 +600,10 @@ HdRenderIndex::_Clear()
600600
// -------------------------------------------------------------------------- //
601601

602602
void
603-
HdRenderIndex::_TrackDelegateTask(HdSceneDelegate* delegate,
604-
SdfPath const& taskId,
605-
HdTaskCreateFnc taskCreateFnc)
603+
HdRenderIndex::_InsertSceneDelegateTask(
604+
HdSceneDelegate* const delegate,
605+
SdfPath const& taskId,
606+
HdLegacyTaskFactorySharedPtr factory)
606607
{
607608
HD_TRACE_FUNCTION();
608609
HF_MALLOC_TAG_FUNCTION();
@@ -611,7 +612,13 @@ HdRenderIndex::_TrackDelegateTask(HdSceneDelegate* delegate,
611612
return;
612613
}
613614

614-
HdTaskSharedPtr const task = taskCreateFnc(delegate, taskId);
615+
if (_IsEnabledSceneIndexEmulation()) {
616+
_emulationSceneIndex->AddLegacyTask(
617+
taskId, delegate, std::move(factory));
618+
return;
619+
}
620+
621+
HdTaskSharedPtr const task = factory->Create(delegate, taskId);
615622
_InsertTask(delegate, taskId, task);
616623
}
617624

@@ -640,6 +647,17 @@ HdRenderIndex::GetTask(SdfPath const& id) const {
640647

641648
void
642649
HdRenderIndex::RemoveTask(SdfPath const& id)
650+
{
651+
if (_IsEnabledSceneIndexEmulation()) {
652+
_emulationSceneIndex->RemovePrim(id);
653+
return;
654+
}
655+
656+
_RemoveTask(id);
657+
}
658+
659+
void
660+
HdRenderIndex::_RemoveTask(SdfPath const& id)
643661
{
644662
HD_TRACE_FUNCTION();
645663
HF_MALLOC_TAG_FUNCTION();

0 commit comments

Comments
 (0)