7 #ifndef PXR_USD_IMAGING_USD_IMAGING_RESOLVED_ATTRIBUTE_CACHE_H
8 #define PXR_USD_IMAGING_USD_IMAGING_RESOLVED_ATTRIBUTE_CACHE_H
24 #include <tbb/concurrent_unordered_map.h>
51 template<
typename Strategy,
typename ImplData=
bool>
56 using _CacheMap = tbb::concurrent_unordered_map<UsdPrim, _Entry, TfHash>;
66 ImplData *implData=
nullptr,
69 , _rootPath(
SdfPath::AbsoluteRootPath())
70 , _cacheVersion(_GetInitialCacheVersion())
71 , _valueOverrides(valueOverrides)
79 , _rootPath(
SdfPath::AbsoluteRootPath())
97 "which is not within the specified root: %s",
100 return Strategy::MakeDefault();
103 return *_GetValue(prim);
111 return &_GetCacheEntryForPrim(prim)->query;
117 _cacheVersion = _GetInitialCacheVersion();
127 if (Strategy::ValueMightBeTimeVarying()) {
156 if (rootPath == _rootPath)
160 _rootPath = rootPath;
178 const std::vector<UsdPrim> &overridesToRemove,
179 std::vector<SdfPath> *dirtySubtreeRoots)
183 if (valueOverrides.empty() && overridesToRemove.empty())
189 const UsdPrim &prim = it->first;
194 if (*_GetValue(prim) == value)
197 valueOverridesToProcess[prim] =
value;
201 const UsdPrim &prim = it->first;
209 bool isDescendantOfProcessedOverride =
false;
210 for (
const SdfPath &processedPath : processedOverridePaths) {
212 isDescendantOfProcessedOverride =
true;
219 if (!isDescendantOfProcessedOverride) {
221 if (_Entry* entry = _GetCacheEntryForPrim(descendant)) {
222 entry->version = _GetInvalidVersion();
225 processedOverridePaths.push_back(prim.
GetPath());
226 dirtySubtreeRoots->push_back(prim.
GetPath());
230 _valueOverrides[prim] =
value;
233 for (
const UsdPrim &prim : overridesToRemove) {
236 size_t numErased = _valueOverrides.
erase(prim);
239 if (numErased == 0) {
243 bool isDescendantOfProcessedOverride =
false;
244 for (
const SdfPath &processedPath : processedOverridePaths) {
245 if (prim.GetPath().HasPrefix(processedPath)) {
246 isDescendantOfProcessedOverride =
true;
253 if (!isDescendantOfProcessedOverride) {
255 if (_Entry* entry = _GetCacheEntryForPrim(descendant)) {
256 entry->version = _GetInvalidVersion();
259 dirtySubtreeRoots->push_back(prim.GetPath());
260 processedOverridePaths.push_back(prim.GetPath());
271 :
value(Strategy::MakeDefault())
272 ,
version(_GetInitialEntryVersion())
283 _Entry(
const _Entry &other)
287 version.store(other.version.load());
290 _Entry(_Entry &&other)
294 version.store(other.version.load());
303 unsigned _GetValidVersion()
const {
return _cacheVersion + 1; }
306 unsigned _GetInvalidVersion()
const {
return _cacheVersion - 1; }
309 static unsigned _GetInitialCacheVersion() {
return 1; }
310 static unsigned _GetInitialEntryVersion() {
311 return _GetInitialCacheVersion()-1;
319 _Entry* _GetCacheEntryForPrim(
const UsdPrim &prim)
const;
324 void _SetCacheEntryForPrim(
const UsdPrim &prim,
326 _Entry* entry)
const;
331 mutable _CacheMap _cache;
339 std::atomic<unsigned> _cacheVersion;
348 template<
typename Strategy,
typename ImplData>
356 unsigned v = entry->version;
357 if (v < _cacheVersion
358 && entry->version.compare_exchange_strong(v,_cacheVersion.load()))
360 entry->value =
value;
361 entry->version = _GetValidVersion();
363 while (entry->version != _GetValidVersion()) {
373 template<
typename Strategy,
typename ImplData>
378 typename _CacheMap::iterator it = _cache.find(prim);
379 if (it != _cache.end()) {
384 e.query = Strategy::MakeQuery(prim, _implData);
385 e.value = Strategy::MakeDefault();
386 e.version = _GetInvalidVersion();
387 return &(_cache.insert(
391 template<
typename Strategy,
typename ImplData>
396 static value_type const default_ = Strategy::MakeDefault();
402 _Entry* entry = _GetCacheEntryForPrim(prim);
403 if (entry->version == _GetValidVersion()) {
405 return &entry->value;
415 typename ValueOverridesMap::const_iterator it =
416 _valueOverrides.find(prim);
417 if (it != _valueOverrides.end()) {
418 _SetCacheEntryForPrim(prim, it->second, entry);
420 _SetCacheEntryForPrim(prim,
421 Strategy::Compute(
this, prim, &entry->query),
424 return &entry->value;
470 ? (xform * (*owner->_GetValue(prim.
GetParent())))
487 while (p && p.
GetPath() != rootPath) {
488 const auto &overIt = ctmOverrides.find(p.
GetPath());
490 if (overIt != ctmOverrides.
end()) {
491 ctm *= overIt->second;
494 if (xf.GetLocalTransformation(&localXf, &reset, time))
611 return *(owner->_GetValue(prim.
GetParent()));
660 _materialPurpose(materialPurpose)
671 return _materialPurpose;
677 {
return _bindingsCache; }
682 {
return _collQueryCache; }
688 const TfToken _materialPurpose;
698 struct UsdImaging_MaterialStrategy {
742 Compute(UsdImaging_MaterialBindingCache
const* owner,
746 TF_DEBUG(USDIMAGING_SHADERS).Msg(
"Looking for \"preview\" material "
808 return query_type(modelApi.GetModelDrawModeAttr());
815 Compute(UsdImaging_DrawModeCache
const* owner,
888 Compute(UsdImaging_PointInstancerIndicesCache
const* owner,
902 VtIntArray protoIndices;
904 TF_WARN(
"Failed to read point instancer protoIndices");
910 for (
size_t instanceId = 0; instanceId < protoIndices.size(); ++instanceId) {
911 size_t protoIndex = protoIndices[instanceId];
913 if (protoIndex >= v.size()) {
914 v.resize(protoIndex + 1);
917 if (mask.size() == 0 || mask[instanceId]) {
918 v[protoIndex].push_back(instanceId);
969 Compute(UsdImaging_CoordSysBindingCache
const* owner,
977 v = *owner->_GetValue(parentPrim);
980 auto _IterateLocalBindings = [&prim](
const UsdBindingVec &localBindings,
983 if (!prim.
GetStage()->GetPrimAtPath(
984 binding.coordSysPrimPath).IsValid()) {
987 TF_WARN(
"UsdImaging: Ignore coordinate system binding to "
988 "non-existent prim <%s>\n",
989 binding.coordSysPrimPath.GetText());
993 for (
size_t id = 0,
n = hdIds.size();
id <
n; ++
id) {
994 if (usdBindings[
id].
name == binding.name) {
996 usdBindings[
id] = binding;
997 hdIds[
id] = binding.bindingRelPath;
1004 usdBindings.push_back(binding);
1005 hdIds.push_back(binding.bindingRelPath);
1018 if (hasLocalBindings && !localBindings.empty()) {
1027 _IterateLocalBindings(localBindings, hdIds, usdBindings);
1071 return query_type(motionAPI.GetNonlinearSampleCountAttr());
1078 Compute(UsdImaging_NonlinearSampleCountCache
const* owner,
1089 return *owner->_GetValue(prim.
GetParent());
1138 return query_type(motionAPI.GetMotionBlurScaleAttr());
1152 return {
value,
true };
1156 return *owner->_GetValue(prim.
GetParent());
1214 v = *owner->_GetValue(parentPrim);
1217 std::vector<UsdGeomPrimvar> primvars =
1219 v ? v->primvars : std::vector<UsdGeomPrimvar>());
1220 if (!primvars.empty()) {
1221 v = std::make_shared<PrimvarRecord>();
1222 v->primvars = std::move(primvars);
1223 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
std::vector< class SdfPath > SdfPathVector
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)
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