4141
4242#include " IECoreScene/ShaderNetwork.h"
4343
44+ #include " IECore/LRUCache.h"
4445#include " IECore/MessageHandler.h"
4546#include " IECore/SimpleTypedData.h"
4647#include " IECore/VectorTypedData.h"
@@ -389,6 +390,62 @@ void populateMaterial( pxr::UsdShadeMaterial &mat, const std::map< const Interne
389390 }
390391}
391392
393+ // / SdfPath is the appropriate cache key for _storage_, but we need a
394+ // / `UsdShadeOutput` for computation. This struct provides the implicit
395+ // / conversion that LRUCache needs to make that possible.
396+ struct ShaderNetworkCacheGetterKey : public pxr ::UsdShadeOutput
397+ {
398+ ShaderNetworkCacheGetterKey ( const pxr::UsdShadeOutput &output )
399+ : pxr::UsdShadeOutput( output )
400+ {
401+ }
402+
403+ operator pxr::SdfPath () const
404+ {
405+ return GetAttr ().GetPath ();
406+ }
407+ };
408+
409+ class ShaderNetworkCache : public LRUCache <pxr::SdfPath, IECoreScene::ConstShaderNetworkPtr, LRUCachePolicy::Parallel, ShaderNetworkCacheGetterKey>
410+ {
411+
412+ public :
413+
414+ ShaderNetworkCache ( size_t maxBytes )
415+ : LRUCache<pxr::SdfPath, IECoreScene::ConstShaderNetworkPtr, LRUCachePolicy::Parallel, ShaderNetworkCacheGetterKey>( getter, maxBytes )
416+ {
417+ }
418+
419+ private :
420+
421+ static IECoreScene::ConstShaderNetworkPtr getter ( const ShaderNetworkCacheGetterKey &key, size_t &cost )
422+ {
423+ IECoreScene::ConstShaderNetworkPtr result;
424+
425+ // / \todo I'm pretty sure that the `readShaderNetwork()` signature is overly complex,
426+ // / and it should just be passed a single `UsdShadeOutput &` like this function.
427+ // / I suspect that `writeShaderNetwork()` could take a single `UsdShadeOutput &` too,
428+ // / for symmetry between the two functions.
429+
430+ pxr::UsdShadeConnectableAPI source;
431+ pxr::TfToken sourceName;
432+ pxr::UsdShadeAttributeType sourceType;
433+ if ( key.GetConnectedSource ( &source, &sourceName, &sourceType ) )
434+ {
435+ pxr::UsdShadeShader s ( source.GetPrim () );
436+ result = ShaderAlgo::readShaderNetwork ( source.GetPrim ().GetParent ().GetPath (), s, sourceName );
437+ }
438+ else
439+ {
440+ result = new IECoreScene::ShaderNetwork ();
441+ }
442+
443+ cost = result->Object ::memoryUsage ();
444+ return result;
445+ }
446+
447+ };
448+
392449} // namespace
393450
394451class USDScene ::Location : public RefCounted
@@ -411,7 +468,8 @@ class USDScene::IO : public RefCounted
411468 IO ( const std::string &fileName, const pxr::UsdStageRefPtr &stage, IndexedIO::OpenMode openMode )
412469 : m_fileName( fileName ), m_openMode( openMode ), m_stage( stage ),
413470 m_rootPrim ( m_stage->GetPseudoRoot () ),
414- m_timeCodesPerSecond( m_stage->GetTimeCodesPerSecond () )
471+ m_timeCodesPerSecond( m_stage->GetTimeCodesPerSecond () ),
472+ m_shaderNetworkCache( 10 * 1024 * 1024 ) // 10Mb
415473 {
416474 }
417475
@@ -489,6 +547,11 @@ class USDScene::IO : public RefCounted
489547 );
490548 }
491549
550+ IECoreScene::ConstShaderNetworkPtr readShaderNetwork ( const pxr::UsdShadeOutput &output )
551+ {
552+ return m_shaderNetworkCache.get ( output );
553+ }
554+
492555 private :
493556
494557 static pxr::UsdStageRefPtr makeStage ( const std::string &fileName, IndexedIO::OpenMode openMode )
@@ -522,6 +585,8 @@ class USDScene::IO : public RefCounted
522585 pxr::UsdShadeMaterialBindingAPI::BindingsCache m_usdBindingsCache;
523586 pxr::UsdShadeMaterialBindingAPI::CollectionQueryCache m_usdCollectionQueryCache;
524587
588+ ShaderNetworkCache m_shaderNetworkCache;
589+
525590};
526591
527592USDScene::USDScene ( const std::string &fileName, IndexedIO::OpenMode openMode )
@@ -910,17 +975,7 @@ ConstObjectPtr USDScene::readAttribute( const SceneInterface::Name &name, double
910975 pxr::UsdShadeOutput o = mat.GetOutput ( n );
911976 if ( o && pxr::UsdAttribute ( o ).IsAuthored () )
912977 {
913- {
914- pxr::UsdShadeConnectableAPI source;
915- pxr::TfToken sourceName;
916- pxr::UsdShadeAttributeType sourceType;
917- if ( o.GetConnectedSource ( &source, &sourceName, &sourceType ) )
918- {
919- pxr::UsdShadeShader s ( source.GetPrim () );
920- return ShaderAlgo::readShaderNetwork ( source.GetPrim ().GetParent ().GetPath (), s, sourceName );
921- }
922- }
923- return new IECoreScene::ShaderNetwork ();
978+ return m_root->readShaderNetwork ( o );
924979 }
925980 }
926981 }
0 commit comments