1 // 2 // Copyright 2016 Pixar 3 // 4 // Licensed under the Apache License, Version 2.0 (the "Apache License") 5 // with the following modification; you may not use this file except in 6 // compliance with the Apache License and the following modification to it: 7 // Section 6. Trademarks. is deleted and replaced with: 8 // 9 // 6. Trademarks. This License does not grant permission to use the trade 10 // names, trademarks, service marks, or product names of the Licensor 11 // and its affiliates, except as required to comply with Section 4(c) of 12 // the License and to reproduce the content of the NOTICE file. 13 // 14 // You may obtain a copy of the Apache License at 15 // 16 // http://www.apache.org/licenses/LICENSE-2.0 17 // 18 // Unless required by applicable law or agreed to in writing, software 19 // distributed under the Apache License with the above modification is 20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 21 // KIND, either express or implied. See the Apache License for the specific 22 // language governing permissions and limitations under the Apache License. 23 // 24 #ifndef PXR_USD_PCP_LAYER_STACK_H 25 #define PXR_USD_PCP_LAYER_STACK_H 26 27 /// \file pcp/layerStack.h 28 29 #include "pxr/pxr.h" 30 #include "pxr/usd/pcp/api.h" 31 #include "pxr/usd/pcp/errors.h" 32 #include "pxr/usd/pcp/layerStackIdentifier.h" 33 #include "pxr/usd/pcp/mapExpression.h" 34 #include "pxr/usd/sdf/layerTree.h" 35 #include "pxr/base/tf/declarePtrs.h" 36 37 #include <tbb/spin_mutex.h> 38 #include <iosfwd> 39 #include <memory> 40 #include <string> 41 #include <vector> 42 43 PXR_NAMESPACE_OPEN_SCOPE 44 45 TF_DECLARE_REF_PTRS(SdfLayer); 46 TF_DECLARE_WEAK_AND_REF_PTRS(PcpLayerStack); 47 TF_DECLARE_WEAK_AND_REF_PTRS(Pcp_LayerStackRegistry); 48 49 class ArResolverContext; 50 class Pcp_LayerStackRegistry; 51 class Pcp_MutedLayers; 52 class PcpLayerStackChanges; 53 class PcpLifeboat; 54 55 /// \class PcpLayerStack 56 /// 57 /// Represents a stack of layers that contribute opinions to composition. 58 /// 59 /// Each PcpLayerStack is identified by a PcpLayerStackIdentifier. This 60 /// identifier contains all of the parameters needed to construct a layer stack, 61 /// such as the root layer, session layer, and path resolver context. 62 /// 63 /// PcpLayerStacks are constructed and managed by a Pcp_LayerStackRegistry. 64 /// 65 class PcpLayerStack : public TfRefBase, public TfWeakBase { 66 PcpLayerStack(const PcpLayerStack&) = delete; 67 PcpLayerStack& operator=(const PcpLayerStack&) = delete; 68 69 public: 70 // See Pcp_LayerStackRegistry for creating layer stacks. 71 PCP_API 72 virtual ~PcpLayerStack(); 73 74 /// Returns the identifier for this layer stack. 75 PCP_API 76 const PcpLayerStackIdentifier& GetIdentifier() const; 77 78 /// Returns the layers in this layer stack in strong-to-weak order. 79 /// Note that this is only the *local* layer stack -- it does not 80 /// include any layers brought in by references inside prims. 81 PCP_API 82 const SdfLayerRefPtrVector& GetLayers() const; 83 84 /// Returns only the session layers in the layer stack in strong-to-weak 85 /// order. 86 PCP_API 87 SdfLayerHandleVector GetSessionLayers() const; 88 89 /// Returns the layer tree representing the structure of this layer 90 /// stack. 91 PCP_API 92 const SdfLayerTreeHandle& GetLayerTree() const; 93 94 /// Returns the layer offset for the given layer, or NULL if the layer 95 /// can't be found or is the identity. 96 PCP_API 97 const SdfLayerOffset* GetLayerOffsetForLayer(const SdfLayerHandle&) const; 98 99 /// Return the layer offset for the given layer, or NULL if the layer 100 /// can't be found or is the identity. 101 PCP_API 102 const SdfLayerOffset* GetLayerOffsetForLayer(const SdfLayerRefPtr&) const; 103 104 /// Returns the layer offset for the layer at the given index in this 105 /// layer stack. Returns NULL if the offset is the identity. 106 PCP_API 107 const SdfLayerOffset* GetLayerOffsetForLayer(size_t layerIdx) const; 108 109 /// Returns the set of layers that were muted in this layer 110 /// stack. 111 PCP_API 112 const std::set<std::string>& GetMutedLayers() const; 113 114 /// Return the list of errors local to this layer stack. GetLocalErrors()115 PcpErrorVector GetLocalErrors() const { 116 return _localErrors ? *_localErrors.get() : PcpErrorVector(); 117 } 118 119 /// Returns true if this layer stack contains the given layer, false 120 /// otherwise. 121 PCP_API 122 bool HasLayer(const SdfLayerHandle& layer) const; 123 PCP_API 124 bool HasLayer(const SdfLayerRefPtr& layer) const; 125 126 /// Return the time codes per second value of the layer stack. This is 127 /// usually the same as the computed time codes per second of the root layer 128 /// but may be computed from the session layer when its present. GetTimeCodesPerSecond()129 double GetTimeCodesPerSecond() const { return _timeCodesPerSecond; } 130 131 /// Returns relocation source-to-target mapping for this layer stack. 132 /// 133 /// This map combines the individual relocation entries found across 134 /// all layers in this layer stack; multiple entries that affect a single 135 /// prim will be combined into a single entry. For instance, if this 136 /// layer stack contains relocations { /A: /B } and { /A/C: /A/D }, this 137 /// map will contain { /A: /B } and { /B/C: /B/D }. This allows consumers 138 /// to go from unrelocated namespace to relocated namespace in a single 139 /// step. 140 PCP_API 141 const SdfRelocatesMap& GetRelocatesSourceToTarget() const; 142 143 /// Returns relocation target-to-source mapping for this layer stack. 144 /// 145 /// See GetRelocatesSourceToTarget for more details. 146 PCP_API 147 const SdfRelocatesMap& GetRelocatesTargetToSource() const; 148 149 /// Returns incremental relocation source-to-target mapping for this layer 150 /// stack. 151 /// 152 /// This map contains the individual relocation entries found across 153 /// all layers in this layer stack; it does not combine ancestral 154 /// entries with descendant entries. For instance, if this 155 /// layer stack contains relocations { /A: /B } and { /A/C: /A/D }, this 156 /// map will contain { /A: /B } and { /A/C: /A/D }. 157 PCP_API 158 const SdfRelocatesMap& GetIncrementalRelocatesSourceToTarget() const; 159 160 /// Returns incremental relocation target-to-source mapping for this layer 161 /// stack. 162 /// 163 /// See GetIncrementalRelocatesTargetToSource for more details. 164 PCP_API 165 const SdfRelocatesMap& GetIncrementalRelocatesTargetToSource() const; 166 167 /// Returns a list of paths to all prims across all layers in this 168 /// layer stack that contained relocates. 169 PCP_API 170 const SdfPathVector& GetPathsToPrimsWithRelocates() const; 171 172 /// Apply the changes in \p changes. This blows caches. It's up to 173 /// the client to pull on those caches again as needed. 174 /// 175 /// Objects that are no longer needed and would be destroyed are 176 /// retained in \p lifeboat and won't be destroyed until \p lifeboat is 177 /// itself destroyed. This gives the client control over the timing 178 /// of the destruction of those objects. Clients may choose to pull 179 /// on the caches before destroying \p lifeboat. That may cause the 180 /// caches to again retain the objects, meaning they won't be destroyed 181 /// when \p lifeboat is destroyed. 182 /// 183 /// For example, if blowing a cache means an SdfLayer is no longer 184 /// needed then \p lifeboat will hold an SdfLayerRefPtr to that layer. 185 /// The client can then pull on that cache, which could cause the 186 /// cache to hold an SdfLayerRefPtr to the layer again. If so then 187 /// destroying \p changes will not destroy the layer. In any case, 188 /// we don't destroy the layer and then read it again. However, if 189 /// the client destroys \p lifeboat before pulling on the cache then 190 /// we would destroy the layer then read it again. 191 PCP_API 192 void Apply(const PcpLayerStackChanges& changes, PcpLifeboat* lifeboat); 193 194 /// Return a PcpMapExpression representing the relocations that affect 195 /// namespace at and below the given path. The value of this 196 /// expression will continue to track the effective relocations if 197 /// they are changed later. 198 PCP_API 199 PcpMapExpression GetExpressionForRelocatesAtPath(const SdfPath &path); 200 201 private: 202 // Only a registry can create a layer stack. 203 friend class Pcp_LayerStackRegistry; 204 // PcpCache needs access to check the _registry. 205 friend class PcpCache; 206 // Needs access to _sublayerSourceInfo 207 friend bool Pcp_NeedToRecomputeDueToAssetPathChange(const PcpLayerStackPtr&); 208 209 // It's a coding error to construct a layer stack with a NULL root layer. 210 PcpLayerStack(const PcpLayerStackIdentifier &identifier, 211 const std::string &fileFormatTarget, 212 const Pcp_MutedLayers &mutedLayers, 213 bool isUsd); 214 215 void _BlowLayers(); 216 void _BlowRelocations(); 217 void _Compute(const std::string &fileFormatTarget, 218 const Pcp_MutedLayers &mutedLayers); 219 220 SdfLayerTreeHandle _BuildLayerStack( 221 const SdfLayerHandle & layer, 222 const SdfLayerOffset & offset, 223 double layerTcps, 224 const ArResolverContext & pathResolverContext, 225 const SdfLayer::FileFormatArguments & layerArgs, 226 const std::string & sessionOwner, 227 const Pcp_MutedLayers & mutedLayers, 228 SdfLayerHandleSet *seenLayers, 229 PcpErrorVector *errors); 230 231 private: 232 /// The identifier that uniquely identifies this layer stack. 233 const PcpLayerStackIdentifier _identifier; 234 /// The registry (1:1 with a PcpCache) this layer stack belongs to. This 235 /// may not be set, particularly when a registry is creating a layer stack 236 /// but before it's been installed in the registry. 237 Pcp_LayerStackRegistryPtr _registry; 238 239 /// Data representing the computed layer stack contents. 240 /// 241 /// This is built by examining the session and root layers for 242 /// sublayers, resolving their asset paths with the path resolver context, 243 /// and recursively building up the layer stack. 244 /// 245 /// Note that this is only the *local* layer stack -- it does not 246 /// include any layers brought in by references inside prims. 247 248 /// Retained references to the layers in the stack, 249 /// in strong-to-weak order. 250 SdfLayerRefPtrVector _layers; 251 252 /// The corresponding map functions for each entry in 'layers'. 253 /// Each map function contains a time offset that should be applied 254 /// to its corresponding layer. 255 std::vector<PcpMapFunction> _mapFunctions; 256 257 /// Stores the computed time codes per second value of the layer stack which 258 /// has some special logic when a session layer is present. 259 double _timeCodesPerSecond; 260 261 /// The tree structure of the layer stack. 262 /// Stored separately because this is needed only occasionally. 263 SdfLayerTreeHandle _layerTree; 264 265 /// Tracks information used to compute sublayer asset paths. 266 struct _SublayerSourceInfo { _SublayerSourceInfo_SublayerSourceInfo267 _SublayerSourceInfo( 268 const SdfLayerHandle& layer_, 269 const std::string& authoredSublayerPath_, 270 const std::string& computedSublayerPath_) 271 : layer(layer_) 272 , authoredSublayerPath(authoredSublayerPath_) 273 , computedSublayerPath(computedSublayerPath_) { } 274 275 SdfLayerHandle layer; 276 std::string authoredSublayerPath; 277 std::string computedSublayerPath; 278 }; 279 280 /// List of source info for sublayer asset path computations. 281 std::vector<_SublayerSourceInfo> _sublayerSourceInfo; 282 283 /// Set of asset paths that were muted in this layer stack. 284 std::set<std::string> _mutedAssetPaths; 285 286 /// The errors, if any, discovered while computing this layer stack. 287 /// NULL if no errors were found (the expected common case). 288 std::unique_ptr<PcpErrorVector> _localErrors; 289 290 /// Pre-computed table of local relocates. 291 SdfRelocatesMap _relocatesSourceToTarget; 292 SdfRelocatesMap _relocatesTargetToSource; 293 SdfRelocatesMap _incrementalRelocatesSourceToTarget; 294 SdfRelocatesMap _incrementalRelocatesTargetToSource; 295 296 /// A map of PcpMapExpressions::Variable instances used to represent 297 /// the current value of relocations given out by 298 /// GetExpressionForRelocatesAtPath(). This map is used to update 299 /// those values when relocations change. 300 typedef std::map<SdfPath, PcpMapExpression::VariableUniquePtr, 301 SdfPath::FastLessThan> _RelocatesVarMap; 302 _RelocatesVarMap _relocatesVariables; 303 tbb::spin_mutex _relocatesVariablesMutex; 304 305 /// List of all prim spec paths where relocations were found. 306 SdfPathVector _relocatesPrimPaths; 307 308 bool _isUsd; 309 }; 310 311 PCP_API 312 std::ostream& operator<<(std::ostream&, const PcpLayerStackPtr&); 313 PCP_API 314 std::ostream& operator<<(std::ostream&, const PcpLayerStackRefPtr&); 315 316 /// Compose the relocation arcs in the given stack of layers, 317 /// putting the results into the given sourceToTarget and targetToSource 318 /// maps. 319 void 320 Pcp_ComputeRelocationsForLayerStack( 321 const SdfLayerRefPtrVector & layers, 322 SdfRelocatesMap *relocatesSourceToTarget, 323 SdfRelocatesMap *relocatesTargetToSource, 324 SdfRelocatesMap *incrementalRelocatesSourceToTarget, 325 SdfRelocatesMap *incrementalRelocatesTargetToSource, 326 SdfPathVector *relocatesPrimPaths); 327 328 // Returns true if \p layerStack should be recomputed due to changes to 329 // any computed asset paths that were used to find or open layers 330 // when originally composing \p layerStack. This may be due to scene 331 // description changes or external changes to asset resolution that 332 // may affect the computation of those asset paths. 333 bool 334 Pcp_NeedToRecomputeDueToAssetPathChange(const PcpLayerStackPtr& layerStack); 335 336 // Returns true if the \p layerStack should be recomputed because 337 // \p changedLayer has had changes that would cause the layer stack to have 338 // a different computed overall time codes per second value. 339 bool 340 Pcp_NeedToRecomputeLayerStackTimeCodesPerSecond( 341 const PcpLayerStackPtr& layerStack, const SdfLayerHandle &changedLayer); 342 343 /// Returns true when the environment variable has been set to disable the 344 /// behavior where differing time codes per second metadata in layers sublayered 345 /// or referenced by another layer are used to apply a layer offset scale to the 346 /// map function. 347 PCP_API 348 bool 349 PcpIsTimeScalingForLayerTimeCodesPerSecondDisabled(); 350 351 PXR_NAMESPACE_CLOSE_SCOPE 352 353 #endif // PXR_USD_PCP_LAYER_STACK_H 354