Skip to content

Commit 5a64a00

Browse files
gitamohrpixar-oss
authored andcommitted
usd: Provide an optimization analogous to one removed in 2393523 where
when computing ResolveInfo, if we're doing so for the purposes of a UsdAttribute::Get(), we eagerly fetch default and fallback values instead of just their types. This way we can avoid refetching them later during _GetValueFromResolveInfoImpl. (Internal change: 2394884)
1 parent 06ac573 commit 5a64a00

File tree

2 files changed

+100
-85
lines changed

2 files changed

+100
-85
lines changed

pxr/usd/usd/stage.cpp

Lines changed: 92 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7515,20 +7515,56 @@ class UsdStage_ResolveInfoAccess
75157515
// Helper structure populated by _GetResolveInfo and _ResolveInfoResolver
75167516
// with extra information accumulated in the process. This allows clients to
75177517
// avoid redoing work.
7518-
template <class T>
75197518
struct UsdStage::_ExtraResolveInfo
75207519
{
7521-
static_assert(std::is_same_v<T, SdfAbstractDataValue> ||
7522-
std::is_same_v<T, VtValue>);
7523-
7520+
// Create an _ExtraResolveInfo but with space for the _ResolveInfoResolver
7521+
// to populate default or fallback values into. This is used as an
7522+
// optimization when we're getting resolve info for the purposes of serving
7523+
// UsdAttribute::Get(), when we know we're going to fetch the value
7524+
// eventually.
7525+
static _ExtraResolveInfo WithDefaultOrFallbackValueStorage() {
7526+
_ExtraResolveInfo ret;
7527+
ret._defaultOrFallback.emplace();
7528+
return ret;
7529+
}
7530+
75247531
_ExtraResolveInfo *_AddNextWeakerInfo() {
75257532
if (!TF_VERIFY(!nextWeaker, "Cannot add weaker info to an "
75267533
"_ExtraResolveInfo that already has it.")) {
75277534
return this;
75287535
}
75297536
nextWeaker = std::make_shared<_ExtraResolveInfo>();
7537+
// Propagate _defaultOrFallback's existence.
7538+
if (_defaultOrFallback) {
7539+
nextWeaker->_defaultOrFallback.emplace();
7540+
}
75307541
return nextWeaker.get();
75317542
}
7543+
7544+
// If this object was created by WithDefaultOrFallbackValueStorage(), return
7545+
// a pointer to a VtValue to store a default or fallback value into. This
7546+
// is a value resolution optimization that avoids a double fetch in case
7547+
// there's just one strongest default or fallback.
7548+
VtValue *GetDefaultOrFallbackStorage() {
7549+
return _defaultOrFallback
7550+
? std::addressof(_defaultOrFallback.value())
7551+
: nullptr;
7552+
}
7553+
7554+
// If this object was created by WithDefaultOrFallbackValueStorage() and a
7555+
// non-empty VtValue was stored to it move the stored value to `val`, delete
7556+
// this object's storage for a default or fallback value, and return true.
7557+
// Otherwise do nothing and return false. After a call to this function,
7558+
// subsequent calls to GetDefaultOrFallbackStorage() return nullptr and this
7559+
// function always returns false.
7560+
bool MoveDefaultOrFallbackValueTo(VtValue *val) const {
7561+
if (_defaultOrFallback && !_defaultOrFallback.value().IsEmpty()) {
7562+
*val = std::move(_defaultOrFallback.value());
7563+
_defaultOrFallback.reset();
7564+
return true;
7565+
}
7566+
return false;
7567+
}
75327568

75337569
// If we're chaining together _ExtraResolveInfos to represent composing
75347570
// value types, this points to the next weaker extra resolve info.
@@ -7545,6 +7581,13 @@ struct UsdStage::_ExtraResolveInfo
75457581
// If the resolve info source is UsdResolveInfoSourceValueClips this will
75467582
// be the Usd_ClipSet containing values for the attribute.
75477583
Usd_ClipSetRefPtr clipSet;
7584+
7585+
private:
7586+
// If not empty, then GetDefaultOrFallbackStorage() returns the address of
7587+
// _defaultOrFallback, so the _ResolveInfoResolver can store one there.
7588+
// It's the raw value from the layer, not transformed to the stage's
7589+
// name/time-space, normally _GetValueFromResolveInfoImpl does that.
7590+
mutable std::optional<VtValue> _defaultOrFallback;
75487591
};
75497592

75507593
Usd_AssetPathContext
@@ -7619,14 +7662,13 @@ UsdStage::_GetAssetPathContext(UsdTimeCode time, const UsdAttribute &attr) const
76197662
//
76207663
// Otherwise compute the full resolve info at `time`, and fill both `infoOut`
76217664
// and `extraInfoOut` and return true.
7622-
template <class T>
76237665
bool
76247666
UsdStage::_GetCompletedResolveInfo(const UsdAttribute &attr,
76257667
UsdTimeCode time,
76267668
const UsdResolveTarget *resolveTarget,
76277669
const UsdResolveInfo &infoIn,
76287670
UsdResolveInfo *infoOut,
7629-
_ExtraResolveInfo<T> *extraInfoOut) const
7671+
_ExtraResolveInfo *extraInfoOut) const
76307672
{
76317673
if (infoIn._source == UsdResolveInfoSourceNone ||
76327674
infoIn._source == UsdResolveInfoSourceFallback) {
@@ -7726,7 +7768,7 @@ UsdStage::_GetValueFromResolveInfoImpl(
77267768
UsdTimeCode time, const UsdAttribute &attr,
77277769
Usd_Interpolator const &interpolator,
77287770
const UsdResolveInfo &infoIn, const UsdResolveTarget *resolveTarget,
7729-
const _ExtraResolveInfo<T> *extraInfo, T *result) const
7771+
const _ExtraResolveInfo *extraInfo, T *result) const
77307772
{
77317773
static_assert(std::is_same_v<T, VtValue> ||
77327774
std::is_same_v<T, SdfAbstractDataValue>);
@@ -7738,10 +7780,11 @@ UsdStage::_GetValueFromResolveInfoImpl(
77387780
// or a nullary call to UsdAttribute::GetResolveInfo(). In this case we
77397781
// need to "complete" the resolveInfo for `time` and fill in an `extraInfo`.
77407782
UsdResolveInfo completedInfo_;
7741-
_ExtraResolveInfo<T> completedExtraInfo_;
7783+
_ExtraResolveInfo completedExtraInfo_ =
7784+
_ExtraResolveInfo::WithDefaultOrFallbackValueStorage();
77427785
const auto &[resolveInfo, extraResolveInfo] =
77437786
[&]() -> std::tuple<const UsdResolveInfo &,
7744-
const _ExtraResolveInfo<T> &> {
7787+
const _ExtraResolveInfo &> {
77457788
if (!extraInfo) {
77467789
if (_GetCompletedResolveInfo(
77477790
attr, time, resolveTarget, infoIn,
@@ -7766,7 +7809,7 @@ UsdStage::_GetValueFromResolveInfoImpl(
77667809
// interpolate the final samples.
77677810

77687811
UsdResolveInfo const *curResolveInfo = &resolveInfo;
7769-
_ExtraResolveInfo<T> const *curExtraResolveInfo = &extraResolveInfo;
7812+
_ExtraResolveInfo const *curExtraResolveInfo = &extraResolveInfo;
77707813

77717814
Usd_InterpolationSampleSeries composedSamples;
77727815
Usd_InterpolationSampleSeries curSamples;
@@ -7948,10 +7991,16 @@ UsdStage::_GetValueFromResolveInfoImpl(
79487991
SdfPath specPath = curResolveInfo->
79497992
_primPathInLayerStack.AppendProperty(attr.GetName());
79507993
Usd_InterpolationSampleSeries defaultSeries(1);
7951-
Usd_DefaultValueResult defValue = Usd_HasDefault(
7952-
curResolveInfo->_layer, specPath, &defaultSeries.front().value);
7953-
TF_VERIFY(defValue == Usd_DefaultValueResult::Found,
7954-
"Resolve info source default has no default value");
7994+
// Fetch a value from curExtraResolveInfo if we have one, otherwise
7995+
// call Usd_HasDefault().
7996+
if (!curExtraResolveInfo->
7997+
MoveDefaultOrFallbackValueTo(&defaultSeries.front().value)) {
7998+
Usd_DefaultValueResult defValue = Usd_HasDefault(
7999+
curResolveInfo->_layer, specPath,
8000+
&defaultSeries.front().value);
8001+
TF_VERIFY(defValue == Usd_DefaultValueResult::Found,
8002+
"Resolve info source default has no default value");
8003+
}
79558004
// Translate to the stage.
79568005
xfValueToStage(defaultSeries.front().value, &specPath);
79578006
// Compose samples over.
@@ -7966,11 +8015,14 @@ UsdStage::_GetValueFromResolveInfoImpl(
79668015
else if (curResolveInfo->_source == UsdResolveInfoSourceFallback) {
79678016
VtValue fallbackValue;
79688017
Usd_InterpolationSampleSeries fallbackSeries(1);
7969-
const bool hasFallback = attr._Prim()->GetPrimDefinition()
7970-
.GetAttributeFallbackValue(
7971-
attr.GetName(), &fallbackSeries.front().value);
7972-
TF_VERIFY(hasFallback,
7973-
"Resolve info source fallback has no fallback value");
8018+
if (!curExtraResolveInfo->
8019+
MoveDefaultOrFallbackValueTo(&fallbackSeries.front().value)) {
8020+
const bool hasFallback = attr._Prim()->GetPrimDefinition()
8021+
.GetAttributeFallbackValue(
8022+
attr.GetName(), &fallbackSeries.front().value);
8023+
TF_VERIFY(hasFallback,
8024+
"Resolve info source fallback has no fallback value");
8025+
}
79748026
// Fallback values require no transformation to the stage space, but
79758027
// they can be composed-over. Fallbacks are always weakest, so we
79768028
// can always break out here.
@@ -8014,7 +8066,8 @@ UsdStage::_GetValueImpl(UsdTimeCode time, const UsdAttribute &attr,
80148066
std::is_same_v<T, SdfAbstractDataValue>);
80158067

80168068
UsdResolveInfo resolveInfo;
8017-
_ExtraResolveInfo<T> extraResolveInfo;
8069+
_ExtraResolveInfo extraResolveInfo =
8070+
_ExtraResolveInfo::WithDefaultOrFallbackValueStorage();
80188071

80198072
TfErrorMark m;
80208073
_GetResolveInfo(attr, &resolveInfo, &time, &extraResolveInfo);
@@ -8842,12 +8895,8 @@ UsdStage::_GetTimeSampleMap(const UsdAttribute &attr,
88428895
}
88438896

88448897
// A 'Resolver' for filling UsdResolveInfo.
8845-
template <typename T>
88468898
struct UsdStage::_ResolveInfoResolver
88478899
{
8848-
static_assert(std::is_same_v<T, SdfAbstractDataValue> ||
8849-
std::is_same_v<T, VtValue>);
8850-
88518900
// Helper to set the value source. Normally this just sets the source from
88528901
// None to `source`, but in the case where we're getting resolve info at no
88538902
// specific time and we encounter a composing default, we continue looking
@@ -8876,7 +8925,7 @@ struct UsdStage::_ResolveInfoResolver
88768925

88778926
explicit _ResolveInfoResolver(const UsdAttribute& attr,
88788927
UsdResolveInfo* resolveInfo,
8879-
UsdStage::_ExtraResolveInfo<T>* extraInfo)
8928+
UsdStage::_ExtraResolveInfo* extraInfo)
88808929
: _attr(attr)
88818930
, _resolveInfo(resolveInfo)
88828931
, _extraInfo(extraInfo)
@@ -8886,10 +8935,8 @@ struct UsdStage::_ResolveInfoResolver
88868935
bool
88878936
ProcessFallback()
88888937
{
8889-
if (const bool hasFallback =
8890-
_attr._Prim()->GetPrimDefinition()
8891-
.template GetAttributeFallbackValue<VtValue>(
8892-
_attr.GetName(), nullptr)) {
8938+
if (_attr._Prim()->GetPrimDefinition().GetAttributeFallbackValue(
8939+
_attr.GetName(), _extraInfo->GetDefaultOrFallbackStorage())) {
88938940
_SetSource(_resolveInfo, UsdResolveInfoSourceFallback);
88948941
return true;
88958942
}
@@ -8922,7 +8969,7 @@ struct UsdStage::_ResolveInfoResolver
89228969
}
89238970

89248971
UsdResolveInfo *nextWeaker = nullptr;
8925-
UsdStage::_ExtraResolveInfo<T>* nextWeakerExtra = nullptr;
8972+
UsdStage::_ExtraResolveInfo *nextWeakerExtra = nullptr;
89268973

89278974
UsdResolveInfoSource thisSource = UsdResolveInfoSourceNone;
89288975
bool didSetSource = false;
@@ -8993,8 +9040,9 @@ struct UsdStage::_ResolveInfoResolver
89939040
} else {
89949041
const std::type_info *valueType = &typeid(void);
89959042

8996-
Usd_DefaultValueResult defValue =
8997-
Usd_HasDefault<VtValue>(layer, specPath, nullptr, &valueType);
9043+
Usd_DefaultValueResult defValue = Usd_HasDefault(
9044+
layer, specPath, _extraInfo->GetDefaultOrFallbackStorage(),
9045+
&valueType);
89989046

89999047
if (defValue == Usd_DefaultValueResult::Found) {
90009048
*foundOpinion = true;
@@ -9070,8 +9118,9 @@ struct UsdStage::_ResolveInfoResolver
90709118
// at the default time. We never get here when resolving a value a
90719119
// numeric time.
90729120
const std::type_info *valueType = &typeid(void);
9073-
Usd_DefaultValueResult defValue =
9074-
Usd_HasDefault<VtValue>(layer, specPath, nullptr, &valueType);
9121+
Usd_DefaultValueResult defValue = Usd_HasDefault(
9122+
layer, specPath, _extraInfo->GetDefaultOrFallbackStorage(),
9123+
&valueType);
90759124

90769125
if (defValue == Usd_DefaultValueResult::Found) {
90779126
_resolveInfo->_source = UsdResolveInfoSourceDefault;
@@ -9171,9 +9220,9 @@ struct UsdStage::_ResolveInfoResolver
91719220
}
91729221

91739222
private:
9174-
const UsdAttribute& _attr;
9175-
UsdResolveInfo* _resolveInfo;
9176-
UsdStage::_ExtraResolveInfo<T>* _extraInfo;
9223+
const UsdAttribute &_attr;
9224+
UsdResolveInfo *_resolveInfo;
9225+
UsdStage::_ExtraResolveInfo *_extraInfo;
91779226

91789227
// For composing value types, when we find a lower-time sample value that
91799228
// doesn't compose and an upper-time sample value that does, that
@@ -9193,49 +9242,47 @@ struct UsdStage::_ResolveInfoResolver
91939242
bool _processingAnimationBlock = false;
91949243
};
91959244

9196-
template <class T>
91979245
void
91989246
UsdStage::_GetResolveInfo(const UsdAttribute &attr,
91999247
UsdResolveInfo *resolveInfo,
92009248
const UsdTimeCode *time,
9201-
_ExtraResolveInfo<T> *extraInfo) const
9249+
_ExtraResolveInfo *extraInfo) const
92029250
{
92039251
auto makeUsdResolverFn = [&attr](bool skipEmptyNodes) {
92049252
return Usd_Resolver(&attr._Prim()->GetPrimIndex(), skipEmptyNodes);
92059253
};
92069254
_GetResolveInfoImpl(attr, resolveInfo, time, extraInfo, makeUsdResolverFn);
92079255
}
92089256

9209-
template <class T>
92109257
void
92119258
UsdStage::_GetResolveInfoWithResolveTarget(
92129259
const UsdAttribute &attr,
92139260
const UsdResolveTarget &resolveTarget,
92149261
UsdResolveInfo *resolveInfo,
92159262
const UsdTimeCode *time,
9216-
_ExtraResolveInfo<T> *extraInfo) const
9263+
_ExtraResolveInfo *extraInfo) const
92179264
{
92189265
auto makeUsdResolverFn = [&resolveTarget](bool skipEmptyNodes) {
92199266
return Usd_Resolver(&resolveTarget, skipEmptyNodes);
92209267
};
92219268
_GetResolveInfoImpl(attr, resolveInfo, time, extraInfo, makeUsdResolverFn);
92229269
}
92239270

9224-
template <class T, class MakeUsdResolverFn>
9271+
template <class MakeUsdResolverFn>
92259272
void
92269273
UsdStage::_GetResolveInfoImpl(
92279274
const UsdAttribute &attr,
92289275
UsdResolveInfo *resolveInfo,
92299276
const UsdTimeCode *time,
9230-
_ExtraResolveInfo<T> *extraInfo,
9277+
_ExtraResolveInfo *extraInfo,
92319278
const MakeUsdResolverFn &makeUsdResolverFn) const
92329279
{
9233-
_ExtraResolveInfo<T> localExtraInfo;
9280+
_ExtraResolveInfo localExtraInfo;
92349281
if (!extraInfo) {
92359282
extraInfo = &localExtraInfo;
92369283
}
92379284

9238-
_ResolveInfoResolver<T> resolver(attr, resolveInfo, extraInfo);
9285+
_ResolveInfoResolver resolver(attr, resolveInfo, extraInfo);
92399286
if (!time) {
92409287
_GetResolvedValueAtTimeImpl(
92419288
attr, &resolver, nullptr, makeUsdResolverFn);
@@ -9413,25 +9460,6 @@ UsdStage::_GetResolvedValueAtTimeImpl(
94139460
}
94149461
}
94159462

9416-
void
9417-
UsdStage::_GetResolveInfo(const UsdAttribute &attr,
9418-
UsdResolveInfo *resolveInfo,
9419-
const UsdTimeCode *time) const
9420-
{
9421-
_GetResolveInfo<VtValue>(attr, resolveInfo, time);
9422-
}
9423-
9424-
void
9425-
UsdStage::_GetResolveInfoWithResolveTarget(
9426-
const UsdAttribute &attr,
9427-
const UsdResolveTarget &resolveTarget,
9428-
UsdResolveInfo *resolveInfo,
9429-
const UsdTimeCode *time) const
9430-
{
9431-
_GetResolveInfoWithResolveTarget<VtValue>(
9432-
attr, resolveTarget, resolveInfo, time);
9433-
}
9434-
94359463
bool
94369464
UsdStage::_GetValueFromResolveInfo(const UsdResolveInfo &info,
94379465
UsdTimeCode time, const UsdAttribute &attr,

0 commit comments

Comments
 (0)