24 #ifndef PXR_USD_IMAGING_USD_IMAGING_RESOLVED_ATTRIBUTE_CACHE_H
25 #define PXR_USD_IMAGING_USD_IMAGING_RESOLVED_ATTRIBUTE_CACHE_H
41 #include <tbb/concurrent_unordered_map.h>
68 template<
typename Strategy,
typename ImplData=
bool>
73 using _CacheMap = tbb::concurrent_unordered_map<UsdPrim, _Entry, TfHash>;
83 ImplData *implData=
nullptr,
86 , _rootPath(
SdfPath::AbsoluteRootPath())
87 , _cacheVersion(_GetInitialCacheVersion())
88 , _valueOverrides(valueOverrides)
96 , _rootPath(
SdfPath::AbsoluteRootPath())
114 "which is not within the specified root: %s",
117 return Strategy::MakeDefault();
120 return *_GetValue(prim);
128 return &_GetCacheEntryForPrim(prim)->query;
134 _cacheVersion = _GetInitialCacheVersion();
144 if (Strategy::ValueMightBeTimeVarying()) {
173 if (rootPath == _rootPath)
177 _rootPath = rootPath;
195 const std::vector<UsdPrim> &overridesToRemove,
196 std::vector<SdfPath> *dirtySubtreeRoots)
200 if (valueOverrides.empty() && overridesToRemove.empty())
206 const UsdPrim &prim = it->first;
211 if (*_GetValue(prim) == value)
214 valueOverridesToProcess[prim] =
value;
218 const UsdPrim &prim = it->first;
226 bool isDescendantOfProcessedOverride =
false;
227 for (
const SdfPath &processedPath : processedOverridePaths) {
229 isDescendantOfProcessedOverride =
true;
236 if (!isDescendantOfProcessedOverride) {
238 if (_Entry* entry = _GetCacheEntryForPrim(descendant)) {
239 entry->version = _GetInvalidVersion();
242 processedOverridePaths.push_back(prim.
GetPath());
243 dirtySubtreeRoots->push_back(prim.
GetPath());
247 _valueOverrides[prim] =
value;
250 for (
const UsdPrim &prim : overridesToRemove) {
253 size_t numErased = _valueOverrides.
erase(prim);
256 if (numErased == 0) {
260 bool isDescendantOfProcessedOverride =
false;
261 for (
const SdfPath &processedPath : processedOverridePaths) {
262 if (prim.GetPath().HasPrefix(processedPath)) {
263 isDescendantOfProcessedOverride =
true;
270 if (!isDescendantOfProcessedOverride) {
272 if (_Entry* entry = _GetCacheEntryForPrim(descendant)) {
273 entry->version = _GetInvalidVersion();
276 dirtySubtreeRoots->push_back(prim.GetPath());
277 processedOverridePaths.push_back(prim.GetPath());
288 :
value(Strategy::MakeDefault())
289 ,
version(_GetInitialEntryVersion())
306 unsigned _GetValidVersion()
const {
return _cacheVersion + 1; }
309 unsigned _GetInvalidVersion()
const {
return _cacheVersion - 1; }
312 static unsigned _GetInitialCacheVersion() {
return 1; }
313 static unsigned _GetInitialEntryVersion() {
314 return _GetInitialCacheVersion()-1;
322 _Entry* _GetCacheEntryForPrim(
const UsdPrim &prim)
const;
327 void _SetCacheEntryForPrim(
const UsdPrim &prim,
329 _Entry* entry)
const;
334 mutable _CacheMap _cache;
342 tbb::atomic<unsigned> _cacheVersion;
351 template<
typename Strategy,
typename ImplData>
359 unsigned v = entry->version;
360 if (v < _cacheVersion
361 && entry->version.compare_and_swap(_cacheVersion, v) ==
v)
363 entry->value =
value;
364 entry->version = _GetValidVersion();
366 while (entry->version != _GetValidVersion()) {
376 template<
typename Strategy,
typename ImplData>
381 typename _CacheMap::const_iterator it = _cache.find(prim);
382 if (it != _cache.end()) {
387 e.query = Strategy::MakeQuery(prim, _implData);
388 e.value = Strategy::MakeDefault();
389 e.version = _GetInvalidVersion();
390 return &(_cache.insert(
394 template<
typename Strategy,
typename ImplData>
399 static value_type const default_ = Strategy::MakeDefault();
405 _Entry* entry = _GetCacheEntryForPrim(prim);
406 if (entry->version == _GetValidVersion()) {
408 return &entry->value;
418 typename ValueOverridesMap::const_iterator it =
419 _valueOverrides.find(prim);
420 if (it != _valueOverrides.end()) {
421 _SetCacheEntryForPrim(prim, it->second, entry);
423 _SetCacheEntryForPrim(prim,
424 Strategy::Compute(
this, prim, &entry->query),
427 return &entry->value;
473 ? (xform * (*owner->_GetValue(prim.
GetParent())))
490 while (p && p.
GetPath() != rootPath) {
491 const auto &overIt = ctmOverrides.find(p.
GetPath());
493 if (overIt != ctmOverrides.
end()) {
494 ctm *= overIt->second;
497 if (xf.GetLocalTransformation(&localXf, &reset, time))
614 return *(owner->_GetValue(prim.
GetParent()));
663 _materialPurpose(materialPurpose)
674 return _materialPurpose;
680 {
return _bindingsCache; }
685 {
return _collQueryCache; }
691 const TfToken _materialPurpose;
701 struct UsdImaging_MaterialStrategy {
745 Compute(UsdImaging_MaterialBindingCache
const* owner,
749 TF_DEBUG(USDIMAGING_SHADERS).Msg(
"Looking for \"preview\" material "
811 return query_type(modelApi.GetModelDrawModeAttr());
818 Compute(UsdImaging_DrawModeCache
const* owner,
891 Compute(UsdImaging_PointInstancerIndicesCache
const* owner,
905 VtIntArray protoIndices;
907 TF_WARN(
"Failed to read point instancer protoIndices");
913 for (
size_t instanceId = 0; instanceId < protoIndices.size(); ++instanceId) {
914 size_t protoIndex = protoIndices[instanceId];
916 if (protoIndex >= v.size()) {
917 v.resize(protoIndex + 1);
920 if (mask.size() == 0 || mask[instanceId]) {
921 v[protoIndex].push_back(instanceId);
972 Compute(UsdImaging_CoordSysBindingCache
const* owner,
980 v = *owner->_GetValue(parentPrim);
983 auto _IterateLocalBindings = [&prim](
const UsdBindingVec &localBindings,
986 if (!prim.
GetStage()->GetPrimAtPath(
987 binding.coordSysPrimPath).IsValid()) {
990 TF_WARN(
"UsdImaging: Ignore coordinate system binding to "
991 "non-existent prim <%s>\n",
992 binding.coordSysPrimPath.GetText());
996 for (
size_t id = 0,
n = hdIds.size();
id <
n; ++
id) {
997 if (usdBindings[
id].
name == binding.name) {
999 usdBindings[
id] = binding;
1000 hdIds[
id] = binding.bindingRelPath;
1007 usdBindings.push_back(binding);
1008 hdIds.push_back(binding.bindingRelPath);
1021 if (hasLocalBindings && !localBindings.empty()) {
1030 _IterateLocalBindings(localBindings, hdIds, usdBindings);
1074 return query_type(motionAPI.GetNonlinearSampleCountAttr());
1081 Compute(UsdImaging_NonlinearSampleCountCache
const* owner,
1092 return *owner->_GetValue(prim.
GetParent());
1141 return query_type(motionAPI.GetMotionBlurScaleAttr());
1155 return {
value,
true };
1159 return *owner->_GetValue(prim.
GetParent());
1217 v = *owner->_GetValue(parentPrim);
1220 std::vector<UsdGeomPrimvar> primvars =
1222 v ? v->primvars : std::vector<UsdGeomPrimvar>());
1223 if (!primvars.empty()) {
1224 v = std::make_shared<PrimvarRecord>();
1225 v->primvars = std::move(primvars);
1226 v->variable =
false;
UsdGeomPrimvarsAPI query_type
USDSHADE_API std::vector< Binding > GetLocalBindings() const
SDF_API const char * GetText() const
UsdTimeCode GetTime() const
Get the current time from which this cache is reading values.
USDSHADE_API bool HasLocalBindings() const
bool Get(T *value, UsdTimeCode time=UsdTimeCode::Default()) const
static value_type Compute(UsdImaging_InheritedPrimvarCache const *owner, UsdPrim const &prim, query_type const *query)
USDGEOM_API std::vector< UsdGeomPrimvar > FindIncrementallyInheritablePrimvars(const std::vector< UsdGeomPrimvar > &inheritedFromAncestors) const
UsdImaging_ResolvedAttributeCache< UsdImaging_PurposeStrategy > UsdImaging_PurposeCache
static value_type ComputeDrawMode(UsdPrim const &prim)
const TfToken & GetMaterialPurpose() const
Returns the material purpose for which bindings must be computed.
bool Get(T *value, UsdTimeCode time=UsdTimeCode::Default()) const
UsdImaging_ResolvedAttributeCache< UsdImaging_MaterialStrategy, UsdImaging_MaterialBindingImplData > UsdImaging_MaterialBindingCache
void SetRootPath(const SdfPath &rootPath)
GT_API const UT_StringHolder time
USDGEOM_API bool ValueMightBeTimeVarying() const
static value_type MakeDefault()
GLsizei const GLfloat * value
static USDSHADE_API const SdfPath GetResolvedTargetPathFromBindingRel(const UsdRelationship &bindingRel)
returns the path of the resolved target identified by bindingRel.
static bool ValueMightBeTimeVarying()
static value_type Compute(UsdImaging_PurposeCache const *owner, UsdPrim const &prim, query_type const *query)
Strategy::value_type value_type
UsdAttributeQuery query_type
static value_type ComputeBlurScale(UsdPrim const &prim, UsdTimeCode time)
void Clear()
Clears all pre-cached values.
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
void UpdateValueOverrides(const ValueOverridesMap &valueOverrides, const std::vector< UsdPrim > &overridesToRemove, std::vector< SdfPath > *dirtySubtreeRoots)
static value_type Compute(UsdImaging_BlurScaleCache const *owner, UsdPrim const &prim, query_type const *query)
static value_type ComputeTransform(UsdPrim const &prim, SdfPath const &rootPath, UsdTimeCode time, const TfHashMap< SdfPath, GfMatrix4d, SdfPath::Hash > &ctmOverrides)
static value_type MakeDefault()
size_type erase(const key_type &key)
Strategy::query_type query_type
USDGEOM_API int ComputeNonlinearSampleCount(UsdTimeCode time=UsdTimeCode::Default()) const
static value_type MakeDefault()
static query_type MakeQuery(UsdPrim const &prim, bool *)
USDGEOM_API TfToken ComputeModelDrawMode(const TfToken &parentDrawMode=TfToken()) const
void ClearCaches()
Clears all of the held caches.
std::shared_ptr< UsdBindingVec > UsdBindingVecPtr
static query_type MakeQuery(UsdPrim const &prim, bool *)
static value_type MakeDefault()
static value_type ComputePurposeInfo(UsdPrim const &prim)
static value_type ComputeNonlinearSampleCount(UsdPrim const &prim, UsdTimeCode time)
~UsdImaging_ResolvedAttributeCache()
VtArray< VtIntArray > value_type
static value_type MakeDefault()
UsdImaging_ResolvedAttributeCache()
Construct a new cache for UsdTimeCode::Default().
TfHashMap< UsdPrim, value_type, TfHash > ValueOverridesMap
USDGEOM_API float ComputeMotionBlurScale(UsdTimeCode time=UsdTimeCode::Default()) const
tbb::concurrent_unordered_map< SdfPath, std::unique_ptr< UsdCollectionAPI::MembershipQuery >, SdfPath::Hash > CollectionQueryCache
static value_type Compute(UsdImaging_PointInstancerIndicesCache const *owner, UsdPrim const &prim, query_type const *query)
UsdImaging_ResolvedAttributeCache< UsdImaging_DrawModeStrategy > UsdImaging_DrawModeCache
UsdImaging_ResolvedAttributeCache< UsdImaging_PointInstancerIndicesStrategy > UsdImaging_PointInstancerIndicesCache
query_type const * GetQuery(const UsdPrim &prim) const
static bool ValueMightBeTimeVarying()
UsdAttributeQuery query_type
static value_type Compute(UsdImaging_XformCache const *owner, UsdPrim const &prim, query_type const *query)
UsdImaging_ResolvedAttributeCache< UsdImaging_NonlinearSampleCountStrategy > UsdImaging_NonlinearSampleCountCache
std::vector< UsdGeomPrimvar > primvars
static value_type MakeDefault()
USDGEOM_API TfToken ComputeVisibility(UsdTimeCode const &time=UsdTimeCode::Default()) const
SDF_API bool IsAbsolutePath() const
Returns whether the path is absolute.
UsdShadeMaterialBindingAPI::CollectionQueryCache & GetCollectionQueryCache()
UsdImaging_ResolvedAttributeCache< UsdImaging_CoordSysBindingStrategy > UsdImaging_CoordSysBindingCache
static query_type MakeQuery(UsdPrim const &prim, bool *)
static query_type MakeQuery(UsdPrim const &prim, bool *)
UsdImaging_ResolvedAttributeCache< UsdImaging_BlurScaleStrategy > UsdImaging_BlurScaleCache
static value_type ComputeVisibility(UsdPrim const &prim, UsdTimeCode time)
static value_type Compute(UsdImaging_DrawModeCache const *owner, UsdPrim const &prim, query_type const *query)
GLuint const GLchar * name
static bool ValueMightBeTimeVarying()
static value_type Compute(UsdImaging_CoordSysBindingCache const *owner, UsdPrim const &prim, query_type const *query)
SDF_API const std::string & GetString() const
static bool ValueMightBeTimeVarying()
USDGEOM_API std::vector< bool > ComputeMaskAtTime(UsdTimeCode time, VtInt64Array const *ids=nullptr) const
USDSHADE_API UsdShadeMaterial ComputeBoundMaterial(BindingsCache *bindingsCache, CollectionQueryCache *collectionQueryCache, const TfToken &materialPurpose=UsdShadeTokens->allPurpose, UsdRelationship *bindingRel=nullptr, bool supportLegacyBindings=true) const
static value_type MakeDefault()
UsdPrim GetParent() const
#define TF_DEBUG(enumVal)
std::vector< class SdfPath > SdfPathVector
A vector of SdfPaths.
SDF_API bool HasPrefix(const SdfPath &prefix) const
UsdImaging_ResolvedAttributeCache< UsdImaging_XfStrategy > UsdImaging_XformCache
UsdAttributeQuery query_type
USD_API UsdStageWeakPtr GetStage() const
~UsdImaging_MaterialBindingImplData()
GT_API const UT_StringHolder version
UsdGeomImageable::PurposeInfo value_type
static bool ValueMightBeTimeVarying()
std::shared_ptr< SdfPathVector > IdVecPtr
USDGEOM_API PurposeInfo ComputePurposeInfo() const
UsdAttributeQuery query_type
static value_type Compute(UsdImaging_NonlinearSampleCountCache const *owner, UsdPrim const &prim, query_type const *query)
UsdShadeMaterialBindingAPI::BindingsCache & GetBindingsCache()
static query_type MakeQuery(UsdPrim const &prim, bool *)
UsdGeomXformable::XformQuery query_type
USDGEOM_API TfStaticData< UsdGeomTokensType > UsdGeomTokens
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
static value_type MakeDefault()
USD_API bool HasAuthoredValue() const
__hostdev__ constexpr T pi()
Pi constant taken from Boost to match old behaviour.
static value_type MakeDefault()
#define PXR_NAMESPACE_CLOSE_SCOPE
static query_type MakeQuery(UsdPrim const &prim, bool *)
UsdImaging_ResolvedAttributeCache(const UsdTimeCode time, ImplData *implData=nullptr, const ValueOverridesMap valueOverrides=ValueOverridesMap())
Construct a new for the specified time.
static query_type MakeQuery(UsdPrim const &prim, ImplData *implData)
static query_type MakeQuery(UsdPrim const &prim, bool *)
static value_type Compute(UsdImaging_MaterialBindingCache const *owner, UsdPrim const &prim, query_type const *query)
SdfPath GetPath() const
Shorthand for GetPrim()->GetPath().
static value_type Compute(UsdImaging_VisCache const *owner, UsdPrim const &prim, query_type const *query)
static value_type ComputePerPrototypeIndices(UsdPrim const &prim, UsdTimeCode time)
static query_type MakeQuery(UsdPrim const &prim, bool *)
static bool ValueMightBeTimeVarying()
tbb::concurrent_unordered_map< SdfPath, std::unique_ptr< BindingsAtPrim >, SdfPath::Hash > BindingsCache
const SdfPath & GetRootPath() const
std::shared_ptr< PrimvarRecord > value_type
#define TF_FOR_ALL(iter, c)
UsdBindingVecPtr usdBindingVecPtr
static bool ValueMightBeTimeVarying()
static value_type MakeDefault()
void SetTime(UsdTimeCode time)
void WorkSwapDestroyAsync(T &obj)
value_type GetValue(const UsdPrim &prim) const
USDGEOM_API UsdAttribute GetProtoIndicesAttr() const
UsdAttributeQuery query_type
UsdImaging_ResolvedAttributeCache< UsdImaging_InheritedPrimvarStrategy > UsdImaging_InheritedPrimvarCache
static bool ValueMightBeTimeVarying()
static constexpr value_type invalidValue
static value_type ComputeMaterialPath(UsdPrim const &prim, ImplData *implData)
static query_type MakeQuery(UsdPrim const &prim, bool *)
UsdImaging_MaterialBindingImplData(const TfToken &materialPurpose)
static bool ValueMightBeTimeVarying()
bool IsInPrototype() const
static const value_type invalidValue
std::vector< UsdShadeCoordSysAPI::Binding > UsdBindingVec