HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cache.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_USD_PCP_CACHE_H
8 #define PXR_USD_PCP_CACHE_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/usd/pcp/api.h"
12 #include "pxr/usd/pcp/dependency.h"
13 #include "pxr/usd/pcp/errors.h"
15 #include "pxr/usd/pcp/primIndex.h"
18 #include "pxr/usd/sdf/path.h"
19 #include "pxr/usd/sdf/pathTable.h"
20 
21 #include "pxr/usd/ar/ar.h"
25 #include "pxr/base/tf/hashset.h"
26 
27 #include <memory>
28 #include <string>
29 #include <unordered_set>
30 #include <vector>
31 
33 
34 // Forward declarations:
35 class PcpChanges;
36 class PcpCacheChanges;
37 class Pcp_Dependencies;
39 class PcpLifeboat;
40 class PcpNodeRef;
41 class PcpMapFunction;
42 
44 TF_DECLARE_WEAK_AND_REF_PTRS(Pcp_LayerStackRegistry);
46 
47 /// \class PcpCache
48 ///
49 /// PcpCache is the context required to make requests of the Pcp
50 /// composition algorithm and cache the results.
51 ///
52 /// Because the algorithms are recursive -- making a request typically
53 /// makes other internal requests to solve subproblems -- caching
54 /// subproblem results is required for reasonable performance, and
55 /// so this cache is the only entrypoint to the algorithms.
56 ///
57 /// There is a set of parameters that affect the composition results:
58 ///
59 /// \li variant fallbacks: per named variant set, an ordered list of
60 /// fallback values to use when composing a prim that defines
61 /// a variant set but does not specify a selection
62 /// \li payload inclusion set: an SdfPath set used to identify which
63 /// prims should have their payloads included during composition;
64 /// this is the basis for explicit control over the "working set"
65 /// of composition
66 /// \li file format target: the file format target that Pcp will request
67 /// when opening scene description layers
68 /// \li "USD mode" configures the Pcp composition algorithm to provide
69 /// only a custom, lighter subset of the full feature set, as needed
70 /// by the Universal Scene Description system
71 ///
72 /// There are a number of different computations that can be requested.
73 /// These include computing a layer stack from a PcpLayerStackIdentifier,
74 /// computing a prim index or prim stack, and computing a property index.
75 ///
76 class PcpCache
77 {
78  PcpCache(PcpCache const &) = delete;
79  PcpCache &operator=(PcpCache const &) = delete;
80 public:
81  /// Construct a PcpCache to compose results for the layer stack identified
82  /// by \a layerStackIdentifier.
83  ///
84  /// If \p fileFormatTarget is given, Pcp will specify \p fileFormatTarget
85  /// as the file format target when searching for or opening a layer.
86  ///
87  /// If \p usd is true, computation of prim indices and composition of prim
88  /// child names are performed without relocates, inherits, permissions,
89  /// symmetry, or payloads, and without populating the prim stack and
90  /// gathering its dependencies.
91  PCP_API
92  PcpCache(const PcpLayerStackIdentifier & layerStackIdentifier,
93  const std::string& fileFormatTarget = std::string(),
94  bool usd = false);
96 
97  /// \name Parameters
98  /// @{
99 
100  /// Get the identifier of the layerStack used for composition.
101  PCP_API
103 
104  /// Get the layer stack for GetLayerStackIdentifier(). Note that
105  /// this will neither compute the layer stack nor report errors.
106  /// So if the layer stack has not been computed yet this will
107  /// return \c NULL. Use ComputeLayerStack() if you need to
108  /// compute the layer stack if it hasn't been computed already
109  /// and/or get errors caused by computing the layer stack.
110  PCP_API
111  PcpLayerStackPtr GetLayerStack() const;
112 
113  /// Return true if this cache's root layer stack is \p layerStack, false
114  /// otherwise. This is functionally equivalent to comparing against the
115  /// result of GetLayerStack(), but does not require constructing a TfWeakPtr
116  /// or any refcount operations.
117  bool HasRootLayerStack(PcpLayerStackRefPtr const &layerStack) const {
118  return layerStack == _layerStack;
119  }
120 
121  /// \overload
122  PCP_API
123  bool HasRootLayerStack(PcpLayerStackPtr const &layerStack) const;
124 
125  /// Return true if the cache is configured in Usd mode.
126  PCP_API
127  bool IsUsd() const;
128 
129  /// Returns the file format target this cache is configured for.
130  PCP_API
131  const std::string& GetFileFormatTarget() const;
132 
133  /// Get the list of fallbacks to attempt to use when evaluating
134  /// variant sets that lack an authored selection.
135  PCP_API
137 
138  /// Set the list of fallbacks to attempt to use when evaluating
139  /// variant sets that lack an authored selection.
140  ///
141  /// If \p changes is not \c NULL then it's adjusted to reflect the
142  /// changes necessary to see the change in standin preferences,
143  /// otherwise those changes are applied immediately.
144  PCP_API
145  void SetVariantFallbacks( const PcpVariantFallbackMap & map,
146  PcpChanges* changes = NULL );
147 
148  /// Return true if the payload is included for the given path.
149  PCP_API
150  bool IsPayloadIncluded(const SdfPath &path) const;
151 
152  /// Returns the payloads requested for inclusion.
153  using PayloadSet = std::unordered_set<SdfPath, SdfPath::Hash>;
154  PCP_API
155  PayloadSet const &GetIncludedPayloads() const;
156 
157  /// Request payloads to be included or excluded from composition.
158  /// \param pathsToInclude is a set of paths to add to the set for
159  /// payload inclusion.
160  /// \param pathsToExclude is a set of paths to remove from the set for
161  /// payload inclusion.
162  /// \param changes if not \c NULL, is adjusted to reflect the changes
163  /// necessary to see the change in payloads; otherwise those
164  /// changes are applied immediately.
165  /// \note If a path is listed in both pathsToInclude and pathsToExclude,
166  /// it will be treated as an inclusion only.
167  ///
168  PCP_API
169  void RequestPayloads( const SdfPathSet & pathsToInclude,
170  const SdfPathSet & pathsToExclude,
171  PcpChanges* changes = NULL );
172 
173  /// Request layers to be muted or unmuted in this cache. Muted layers
174  /// are ignored during composition and do not appear in any layer
175  /// stacks. The root layer of this stage may not be muted; attempting
176  /// to do so will generate a coding error. If the root layer of a
177  /// reference or payload layer stack is muted, the behavior is as if
178  /// the muted layer did not exist, which means a composition error will
179  /// be generated.
180  ///
181  /// A canonical identifier for each layer in \p layersToMute will be
182  /// computed using ArResolver::CreateIdentifier using the cache's root
183  /// layer as the anchoring asset. If an identifier contains a file
184  /// format target that matches this cache's file format target, that
185  /// argument will be removed from the identifier. Any layer encountered
186  /// during composition with the same canonical identifier will be
187  /// considered muted and ignored.
188  ///
189  /// Note that muting a layer will cause this cache to release all
190  /// references to that layer. If no other client is holding on to
191  /// references to that layer, it will be unloaded. In this case, if
192  /// there are unsaved edits to the muted layer, those edits are lost.
193  /// Since anonymous layers are not serialized, muting an anonymous
194  /// layer will cause that layer and its contents to be lost in this
195  /// case.
196  ///
197  /// If \p changes is not \c nullptr, it is adjusted to reflect the
198  /// changes necessary to see the change in muted layers. Otherwise,
199  /// those changes are applied immediately.
200  ///
201  /// \p newLayersMuted and \p newLayersUnmuted contains the pruned vector
202  /// of layers which are muted or unmuted by this call to RequestLayerMuting.
203  ///
204  PCP_API
205  void RequestLayerMuting(const std::vector<std::string>& layersToMute,
206  const std::vector<std::string>& layersToUnmute,
207  PcpChanges* changes = nullptr,
208  std::vector<std::string>* newLayersMuted = nullptr,
209  std::vector<std::string>* newLayersUnmuted =
210  nullptr);
211 
212  /// Returns the list of canonical identifiers for muted layers
213  /// in this cache. See documentation on RequestLayerMuting for
214  /// more details.
215  PCP_API
216  const std::vector<std::string>& GetMutedLayers() const;
217 
218  /// Returns true if the layer specified by \p layerIdentifier is
219  /// muted in this cache, false otherwise. If \p layerIdentifier
220  /// is relative, it is assumed to be relative to this cache's
221  /// root layer. See documentation on RequestLayerMuting for
222  /// more details.
223  PCP_API
224  bool IsLayerMuted(const std::string& layerIdentifier) const;
225 
226  /// Returns true if the layer specified by \p layerIdentifier is
227  /// muted in this cache, false otherwise. If \p layerIdentifier
228  /// is relative, it is assumed to be relative to \p anchorLayer.
229  /// If \p canonicalMutedLayerIdentifier is supplied, it will be
230  /// populated with the canonical identifier of the muted layer if this
231  /// function returns true. See documentation on RequestLayerMuting
232  /// for more details.
233  PCP_API
234  bool IsLayerMuted(const SdfLayerHandle& anchorLayer,
235  const std::string& layerIdentifier,
236  std::string* canonicalMutedLayerIdentifier
237  = nullptr) const;
238 
239  /// Returns parameter object containing all inputs for the prim index
240  /// computation used by this cache.
241  ///
242  /// Note that this inputs object holds raw pointers to internal objects
243  /// within this cache as well as a raw pointer to the cache itself. In other
244  /// words, even if a copy is made of this inputs structure, it still may
245  /// only be used within the lifetime of this cache.
246  PCP_API
247  const PcpPrimIndexInputs &GetPrimIndexInputs() const;
248 
249  /// @}
250 
251  /// \name Computations
252  /// @{
253 
254  /// Returns the layer stack for \p identifier if it exists, otherwise
255  /// creates a new layer stack for \p identifier. This returns \c NULL
256  /// if \p identifier is invalid (i.e. its root layer is \c NULL).
257  /// \p allErrors will contain any errors encountered while creating a
258  /// new layer stack. It'll be unchanged if the layer stack already existed.
259  PCP_API
260  PcpLayerStackRefPtr
261  ComputeLayerStack(const PcpLayerStackIdentifier &identifier,
262  PcpErrorVector *allErrors);
263 
264  /// Returns the layer stack for \p identifier if it has been computed
265  /// and cached, otherwise returns \c NULL.
266  PCP_API
267  PcpLayerStackPtr
268  FindLayerStack(const PcpLayerStackIdentifier &identifier) const;
269 
270  /// Return true if \p layerStack is used by this cache in its composition,
271  /// false otherwise.
272  PCP_API
273  bool UsesLayerStack(const PcpLayerStackPtr &layerStack) const;
274 
275  /// Compute and return a reference to the cached result for the
276  /// prim index for the given path. \p allErrors will contain any errors
277  /// encountered while performing this operation.
278  PCP_API
279  const PcpPrimIndex &
280  ComputePrimIndex(const SdfPath &primPath, PcpErrorVector *allErrors);
281 
282  /// Compute PcpPrimIndexes in the subtree rooted at path in parallel,
283  /// recursing to children based on the supplied \p childrenPred. Also
284  /// include payloads not already in this cache's included payloads (see
285  /// GetIncludedPayloads()) according to \p payloadPred.
286  ///
287  /// This is similar to ComputePrimIndex(), except it computes an entire
288  /// subtree of indexes in parallel so it can be much more efficient. This
289  /// function invokes both \p childrenPred and \p payloadPred concurrently,
290  /// so it must be safe to do so.
291  ///
292  /// When a PcpPrimIndex computation completes invoke \p childrenPred,
293  /// passing it the PcpPrimIndex. If \p childrenPred returns true, continue
294  /// indexing children prim indexes. In this case, \p childrenPred may
295  /// provide a list of names of the children prim indexes to compute.
296  /// If it does not, all children prim indexes will be computed.
297  /// If \p childrenPred returns false, stop indexing in that subtree.
298  ///
299  /// If payloads discovered during indexing do not already appear in this
300  /// cache's set of included payloads, invoke \p payloadPred, passing it the
301  /// path for the prim with the payload. If \p payloadPred returns true,
302  /// include its payload and add it to the cache's set of included payloads
303  /// upon completion.
304  template <class ChildrenPredicate, class PayloadPredicate>
306  PcpErrorVector *allErrors,
307  const ChildrenPredicate &childrenPred,
308  const PayloadPredicate &payloadPred) {
309  ComputePrimIndexesInParallel(SdfPathVector(1, path), allErrors,
310  childrenPred, payloadPred);
311  }
312 
313  /// Vectorized form of ComputePrimIndexesInParallel(). Equivalent to
314  /// invoking that method for each path in \p paths, but more efficient.
315  template <class ChildrenPredicate, class PayloadPredicate>
317  PcpErrorVector *allErrors,
318  const ChildrenPredicate &childrenPred,
319  const PayloadPredicate &payloadPred) {
320  _UntypedIndexingChildrenPredicate cp(&childrenPred);
321  _UntypedIndexingPayloadPredicate pp(&payloadPred);
322  _ComputePrimIndexesInParallel(paths, allErrors, cp, pp);
323  }
324 
325  /// Returns a pointer to the cached computed prim index for the given
326  /// path, or NULL if it has not been computed.
327  PCP_API
328  const PcpPrimIndex *
329  FindPrimIndex(const SdfPath &primPath) const;
330 
331  /// Run the given \p callback on every prim index in the cache.
332  /// The callback must have the signature: void(const PcpPrimIndex&).
333  template <class Callback>
334  void
335  ForEachPrimIndex(const Callback& callback) const
336  {
338  _ForEachPrimIndex(fn);
339  }
340 
341  /// Compute and return a reference to the cached result for the
342  /// property index for the given path. \p allErrors will contain any
343  /// errors encountered while performing this operation.
344  PCP_API
345  const PcpPropertyIndex &
346  ComputePropertyIndex(const SdfPath &propPath, PcpErrorVector *allErrors);
347 
348  /// Returns a pointer to the cached computed property index for the given
349  /// path, or NULL if it has not been computed.
350  PCP_API
351  const PcpPropertyIndex *
352  FindPropertyIndex(const SdfPath &propPath) const;
353 
354  /// Compute the relationship target paths for the relationship at
355  /// \p relationshipPath into \p paths. If \p localOnly is \c true then
356  /// this will compose relationship targets from local nodes only. If
357  /// \p stopProperty is not \c NULL then this will stop composing
358  /// relationship targets at \p stopProperty, including \p stopProperty
359  /// iff \p includeStopProperty is \c true. If not \c NULL, \p deletedPaths
360  /// will be populated with target paths whose deletion contributed to
361  /// the computed result. \p allErrors will contain any errors encountered
362  /// while performing this operation.
363  PCP_API
364  void
365  ComputeRelationshipTargetPaths(const SdfPath &relationshipPath,
366  SdfPathVector *paths,
367  bool localOnly,
368  const SdfSpecHandle &stopProperty,
369  bool includeStopProperty,
370  SdfPathVector *deletedPaths,
371  PcpErrorVector *allErrors);
372 
373  /// Compute the attribute connection paths for the attribute at
374  /// \p attributePath into \p paths. If \p localOnly is \c true then
375  /// this will compose attribute connections from local nodes only. If
376  /// \p stopProperty is not \c NULL then this will stop composing
377  /// attribute connections at \p stopProperty, including \p stopProperty
378  /// iff \p includeStopProperty is \c true. If not \c NULL, \p deletedPaths
379  /// will be populated with connection paths whose deletion contributed to
380  /// the computed result. \p allErrors will contain any errors encountered
381  /// while performing this operation.
382  PCP_API
383  void
384  ComputeAttributeConnectionPaths(const SdfPath &attributePath,
385  SdfPathVector *paths,
386  bool localOnly,
387  const SdfSpecHandle &stopProperty,
388  bool includeStopProperty,
389  SdfPathVector *deletedPaths,
390  PcpErrorVector *allErrors);
391 
392  /// @}
393  /// \name Dependencies
394  /// @{
395 
396  /// Returns set of all layers used by this cache.
397  PCP_API
399 
400  /// Return a number that can be used to determine whether or not the set of
401  /// layers used by this cache may have changed or not. For example, if one
402  /// calls GetUsedLayers() and saves the GetUsedLayersRevision(), and then
403  /// later calls GetUsedLayersRevision() again, if the number is unchanged,
404  /// then GetUsedLayers() is guaranteed to be unchanged as well.
405  PCP_API
406  size_t GetUsedLayersRevision() const;
407 
408  /// Returns set of all root layers used by this cache.
409  PCP_API
411 
412  /// Returns every computed & cached layer stack that includes \p layer.
413  PCP_API
414  const PcpLayerStackPtrVector&
415  FindAllLayerStacksUsingLayer(const SdfLayerHandle& layer) const;
416 
417  /// Run the given \p callbcack on every layer stack used by prim
418  /// indexes in the cache. The callback must have the signature:
419  /// void(const PcpLayerStackPtr&).
420  template <class Callback>
421  void
422  ForEachLayerStack(const Callback& callback) const
423  {
425  _ForEachLayerStack(fn);
426  }
427 
428  /// Returns dependencies on the given site of scene description,
429  /// as discovered by the cached index computations.
430  ///
431  /// \param depMask specifies what classes of dependency to include;
432  /// see PcpDependencyFlags for details
433  /// \param recurseOnSite includes incoming dependencies on
434  /// children of sitePath
435  /// \param recurseOnIndex extends the result to include all PcpCache
436  /// child indexes below discovered results
437  /// \param filterForExistingCachesOnly filters the results to only
438  /// paths representing computed prim and property index caches;
439  /// otherwise a recursively-expanded result can include
440  /// un-computed paths that are expected to depend on the site
441  PCP_API
443  FindSiteDependencies(const PcpLayerStackPtr& siteLayerStack,
444  const SdfPath& sitePath,
445  PcpDependencyFlags depMask,
446  bool recurseOnSite,
447  bool recurseOnIndex,
448  bool filterForExistingCachesOnly) const;
449 
450  /// Returns dependencies on the given site of scene description,
451  /// as discovered by the cached index computations.
452  ///
453  /// This method overload takes a site layer rather than a layer
454  /// stack. It will check every layer stack using that layer, and
455  /// apply any relevant sublayer offsets to the map functions in the
456  /// returned PcpDependencyVector.
457  ///
458  /// See the other method for parameter details.
459  PCP_API
461  FindSiteDependencies(const SdfLayerHandle& siteLayer,
462  const SdfPath& sitePath,
463  PcpDependencyFlags depMask,
464  bool recurseOnSite,
465  bool recurseOnIndex,
466  bool filterForExistingCachesOnly) const;
467 
468  /// Returns \c true if an opinion for the site at \p localPcpSitePath
469  /// in the cache's layer stack can be provided by an opinion in \p layer,
470  /// \c false otherwise. If \c true and \p allowedPathInLayer is not
471  /// \c NULL then it's set to a path in \p layer that would provide an
472  /// opinion.
473  ///
474  /// This returns \c false if no prim index has yet been computed for
475  /// \p localPcpSitePath.
476  PCP_API
477  bool CanHaveOpinionForSite(const SdfPath& localPcpSitePath,
478  const SdfLayerHandle& layer,
479  SdfPath* allowedPathInLayer) const;
480 
481  /// Returns a vector of sublayer asset paths used in the layer stack
482  /// that didn't resolve to valid assets.
483  PCP_API
484  std::vector<std::string> GetInvalidSublayerIdentifiers() const;
485 
486  /// Returns true if \p identifier was used as a sublayer path in a
487  /// layer stack but did not identify a valid layer. This is functionally
488  /// equivalent to examining the values in the vector returned by
489  /// GetInvalidSublayerIdentifiers, but more efficient.
490  PCP_API
491  bool IsInvalidSublayerIdentifier(const std::string& identifier) const;
492 
493  /// Returns a map of prim paths to asset paths used by that prim
494  /// (e.g. in a reference) that didn't resolve to valid assets.
495  PCP_API
496  std::map<SdfPath, std::vector<std::string>, SdfPath::FastLessThan>
497  GetInvalidAssetPaths() const;
498 
499  /// Returns true if \p resolvedAssetPath was used by a prim (e.g. in
500  /// a reference) but did not resolve to a valid asset. This is
501  /// functionally equivalent to examining the values in the map returned
502  /// by GetInvalidAssetPaths, but more efficient.
503  PCP_API
504  bool IsInvalidAssetPath(const std::string& resolvedAssetPath) const;
505 
506  /// Returns true if any prim index in this cache has a dependency on a
507  /// dynamic file format argument field.
508  PCP_API
510 
511  /// Returns true if any prim index in this cache has a dependency on a
512  /// dynamic file format argument attribute's default value field.
513  PCP_API
515 
516  /// Returns true if the given \p field is the name of a field that
517  /// was composed while generating dynamic file format arguments for any prim
518  /// index in this cache.
519  PCP_API
520  bool IsPossibleDynamicFileFormatArgumentField(const TfToken &field) const;
521 
522  /// Returns true if the given \p attributeName is the name of an attribute
523  /// whose default value field was composed while generating dynamic file
524  /// format arguments for any prim index in this cache.
525  PCP_API
527  const TfToken &attributeName) const;
528 
529  /// Returns the dynamic file format dependency data object for the prim
530  /// index with the given \p primIndexPath. This will return an empty
531  /// dependency data if either there is no cache prim index for the path or
532  /// if the prim index has no dynamic file formats that it depends on.
533  PCP_API
536  const SdfPath &primIndexPath) const;
537 
538  /// Returns the list of prim index paths that depend on one or more
539  /// expression variables from \p layerStack.
540  PCP_API
542  const PcpLayerStackPtr &layerStack) const;
543 
544  /// Returns the set of expression variables in \p layerStack that are
545  /// used by the prim index at \p primIndexPath.
546  PCP_API
547  const std::unordered_set<std::string>&
549  const SdfPath &primIndexPath,
550  const PcpLayerStackPtr &layerStack) const;
551 
552  /// @}
553 
554  /// \name Change handling
555  /// @{
556 
557  /// Apply the changes in \p changes. This blows caches. It's up to
558  /// the client to pull on those caches again as needed.
559  ///
560  /// Objects that are no longer needed and would be destroyed are
561  /// retained in \p lifeboat and won't be destroyed until \p lifeboat is
562  /// itself destroyed. This gives the client control over the timing
563  /// of the destruction of those objects. Clients may choose to pull
564  /// on the caches before destroying \p lifeboat. That may cause the
565  /// caches to again retain the objects, meaning they won't be destroyed
566  /// when \p lifeboat is destroyed.
567  ///
568  /// For example, if blowing a cache means an SdfLayer is no longer
569  /// needed then \p lifeboat will hold an SdfLayerRefPtr to that layer.
570  /// The client can then pull on that cache, which could cause the
571  /// cache to hold an SdfLayerRefPtr to the layer again. If so then
572  /// destroying \p changes will not destroy the layer. In any case,
573  /// we don't destroy the layer and then read it again. However, if
574  /// the client destroys \p lifeboat before pulling on the cache then
575  /// we would destroy the layer then read it again.
576  PCP_API
577  void Apply(const PcpCacheChanges& changes, PcpLifeboat* lifeboat);
578 
579  /// Reload the layers of the layer stack, except session layers
580  /// and sublayers of session layers. This will also try to load
581  /// sublayers in this cache's layer stack that could not be loaded
582  /// previously. It will also try to load any referenced or payloaded
583  /// layer that could not be loaded previously. Clients should
584  /// subsequently \c Apply() \p changes to use any now-valid layers.
585  PCP_API
586  void Reload(PcpChanges* changes);
587 
588  /// Reload every layer used by the prim at \p primPath that's across
589  /// a reference or payload. Clients should subsequently apply the
590  /// changes to use any now valid layers.
591  ///
592  /// Note: If a reference or payload was to an invalid asset and this
593  /// asset is valid upon reloading then this call will not necessarily
594  /// reload every layer accessible across the reference or payload.
595  /// For example, say prim R has an invalid reference and prim Q has a
596  /// valid reference to layer X with sublayer Y. If on reload R now
597  /// has a valid reference to layer Z with sublayer Y, we will load Z
598  /// but we will not reload Y.
599  PCP_API
600  void ReloadReferences(PcpChanges* changes, const SdfPath& primPath);
601 
602  /// @}
603 
604  /// \name Diagnostics
605  /// @{
606 
607  /// Prints various statistics about the data stored in this cache.
608  PCP_API
609  void PrintStatistics() const;
610 
611  /// @}
612 
613 private:
614  friend class PcpChanges;
615  friend class Pcp_Dependencies;
616  friend class Pcp_Statistics;
617 
618  struct _ParallelIndexer;
619 
620  // Helper struct to type-erase a children predicate for the duration of
621  // ComputePrimIndexesInParallel.
622  //
623  // This lets us achieve two goals. First, clients may pass any arbitrary
624  // type as a predicate (e.g. they do not have to derive some base class).
625  // Second, it lets us keep the parallel indexing implementation in the .cpp
626  // file, avoiding any large template code instantiation.
627  //
628  // The cost we pay is this very thin indirect call. We instantiate a
629  // function template with the client's predicate type that simply does a
630  // typecast and predicate invocation, and pass that function pointer into
631  // the implementation. There is no heap allocation, no predicate copy, no
632  // argument marshalling, etc.
633  struct _UntypedIndexingChildrenPredicate {
634  _UntypedIndexingChildrenPredicate() : pred(nullptr), invoke(nullptr) {}
635  template <class Pred>
636  explicit _UntypedIndexingChildrenPredicate(const Pred *pred)
637  : pred(pred), invoke(_Invoke<Pred>) {}
638 
639  inline bool operator()(const PcpPrimIndex &index,
640  TfTokenVector *childNamesToCompose) const {
641  return invoke(pred, index, childNamesToCompose);
642  }
643  private:
644  template <class Pred>
645  static bool _Invoke(const void *pred, const PcpPrimIndex &index,
646  TfTokenVector *namesToCompose) {
647  return (*static_cast<const Pred *>(pred))(index, namesToCompose);
648  }
649  const void *pred;
650  bool (*invoke)(const void *, const PcpPrimIndex &, TfTokenVector *);
651  };
652 
653  // See doc for _UntypedIndexingChildrenPredicate above. This does the same
654  // for the payload inclusion predicate.
655  struct _UntypedIndexingPayloadPredicate {
656  template <class Pred>
657  explicit _UntypedIndexingPayloadPredicate(const Pred *pred)
658  : pred(pred), invoke(_Invoke<Pred>) {}
659 
660  inline bool operator()(const SdfPath &path) const {
661  return invoke(pred, path);
662  }
663  private:
664  template <class Pred>
665  static bool _Invoke(const void *pred, const SdfPath &path) {
666  return (*static_cast<const Pred *>(pred))(path);
667  }
668  const void *pred;
669  bool (*invoke)(const void *, const SdfPath &);
670  };
671 
672  // Internal helper for recursive indexing.
673  const PcpPrimIndex &
674  _ComputePrimIndexWithCompatibleInputs(
675  const SdfPath & path, const PcpPrimIndexInputs &inputs,
676  PcpErrorVector *allErrors);
677 
678  // Friend to allow low-level indexing code access to the above.
679  friend const PcpPrimIndex &
681  PcpCache &cache,
682  const SdfPath & path, const PcpPrimIndexInputs &inputs,
683  PcpErrorVector *allErrors);
684 
685  // Parallel indexing implementation.
686  PCP_API
687  void _ComputePrimIndexesInParallel(
688  const SdfPathVector &paths,
689  PcpErrorVector *allErrors,
690  _UntypedIndexingChildrenPredicate childrenPred,
691  _UntypedIndexingPayloadPredicate payloadPred);
692 
693  void _RemovePrimCache(const SdfPath& primPath, PcpLifeboat* lifeboat);
694  void _RemovePrimAndPropertyCaches(const SdfPath& root,
695  PcpLifeboat* lifeboat);
696  void _RemovePropertyCache(const SdfPath& root, PcpLifeboat* lifeboat);
697  void _RemovePropertyCaches(const SdfPath& root, PcpLifeboat* lifeboat);
698 
699  // Returns the prim index for \p path if it exists, NULL otherwise.
700  PcpPrimIndex* _GetPrimIndex(const SdfPath& path);
701  const PcpPrimIndex* _GetPrimIndex(const SdfPath& path) const;
702 
703  // Returns the property index for \p path if it exists, NULL otherwise.
704  PcpPropertyIndex* _GetPropertyIndex(const SdfPath& path);
705  const PcpPropertyIndex* _GetPropertyIndex(const SdfPath& path) const;
706 
707  PCP_API
708  void _ForEachPrimIndex(
709  const TfFunctionRef<void(const PcpPrimIndex&)>& fn) const;
710 
711  PCP_API
712  void _ForEachLayerStack(
713  const TfFunctionRef<void(const PcpLayerStackPtr&)>& fn) const;
714 
715 private:
716  // Fixed evaluation parameters, set when the cache is created. Note that
717  // _rootLayer and _sessionLayer are not const because we want to mutate them
718  // to enable parallel teardown in the destructor.
719  SdfLayerRefPtr _rootLayer;
720  SdfLayerRefPtr _sessionLayer;
721  const PcpLayerStackIdentifier _layerStackIdentifier;
722 
723  // Flag that configures PcpCache to use the restricted set of USD features.
724  // Currently it governs whether relocates, inherits, permissions,
725  // symmetry, or payloads are considered, and whether the prim stack
726  // is populated and its depdencies gathered during computation of
727  // prim indices and composition of prim child names.
728  const bool _usd;
729 
730  // File format target for all scene description layers this cache will
731  // find or open during prim index computation.
732  const std::string _fileFormatTarget;
733 
734  // The layer stack for this cache. Holding this by ref ptr means we
735  // hold all of our local layers by ref ptr (including the root and
736  // session layers, again).
737  PcpLayerStackRefPtr _layerStack;
738 
739  // Modifiable evaluation parameters.
740  // Anything that changes these should also yield a PcpChanges
741  // value describing the necessary cache invalidation.
742  PayloadSet _includedPayloads;
743  PcpVariantFallbackMap _variantFallbackMap;
744 
745  // The default prim index inputs used when computing a prim index within
746  // this cache.
747  PcpPrimIndexInputs _primIndexInputs;
748 
749  // Cached computation types.
750  typedef Pcp_LayerStackRegistryRefPtr _LayerStackCache;
751  typedef SdfPathTable<PcpPrimIndex> _PrimIndexCache;
752  typedef SdfPathTable<PcpPropertyIndex> _PropertyIndexCache;
753 
754  // Cached computations.
755  _LayerStackCache _layerStackCache;
756  _PrimIndexCache _primIndexCache;
757  _PropertyIndexCache _propertyIndexCache;
758  std::unique_ptr<Pcp_Dependencies> _primDependencies;
759 
760  // Parallel indexer state.
761  std::unique_ptr<_ParallelIndexer> _parallelIndexer;
762 };
763 
765 
766 #endif // PXR_USD_PCP_CACHE_H
PCP_API bool CanHaveOpinionForSite(const SdfPath &localPcpSitePath, const SdfLayerHandle &layer, SdfPath *allowedPathInLayer) const
std::vector< PcpDependency > PcpDependencyVector
Definition: dependency.h:115
void ComputePrimIndexesInParallel(const SdfPathVector &paths, PcpErrorVector *allErrors, const ChildrenPredicate &childrenPred, const PayloadPredicate &payloadPred)
Definition: cache.h:316
PCP_API bool IsPayloadIncluded(const SdfPath &path) const
Return true if the payload is included for the given path.
PCP_API void Reload(PcpChanges *changes)
PCP_API bool IsLayerMuted(const std::string &layerIdentifier) const
PCP_API bool HasAnyDynamicFileFormatArgumentFieldDependencies() const
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
PCP_API const PcpPropertyIndex & ComputePropertyIndex(const SdfPath &propPath, PcpErrorVector *allErrors)
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
PCP_API const std::string & GetFileFormatTarget() const
Returns the file format target this cache is configured for.
PCP_API PcpDependencyVector FindSiteDependencies(const PcpLayerStackPtr &siteLayerStack, const SdfPath &sitePath, PcpDependencyFlags depMask, bool recurseOnSite, bool recurseOnIndex, bool filterForExistingCachesOnly) const
PCP_API ~PcpCache()
Definition: cache.h:76
Definition: spec.h:32
PCP_API SdfLayerHandleSet GetUsedRootLayers() const
Returns set of all root layers used by this cache.
std::set< SdfHandleTo< SdfLayer >::Handle > SdfLayerHandleSet
PCP_API bool IsUsd() const
Return true if the cache is configured in Usd mode.
PCP_API bool HasAnyDynamicFileFormatArgumentAttributeDependencies() const
PCP_API const std::vector< std::string > & GetMutedLayers() const
PCP_API const PcpPrimIndex & ComputePrimIndex(const SdfPath &primPath, PcpErrorVector *allErrors)
PCP_API std::vector< std::string > GetInvalidSublayerIdentifiers() const
OutGridT const XformOp bool bool
PCP_API const PcpDynamicFileFormatDependencyData & GetDynamicFileFormatArgumentDependencyData(const SdfPath &primIndexPath) const
GLenum GLuint GLint GLint layer
Definition: glcorearb.h:1299
PCP_API bool IsInvalidAssetPath(const std::string &resolvedAssetPath) const
friend const PcpPrimIndex & Pcp_ComputePrimIndexWithCompatibleInputs(PcpCache &cache, const SdfPath &path, const PcpPrimIndexInputs &inputs, PcpErrorVector *allErrors)
PCP_API const SdfPathVector & GetPrimsUsingExpressionVariablesFromLayerStack(const PcpLayerStackPtr &layerStack) const
PCP_API void ComputeAttributeConnectionPaths(const SdfPath &attributePath, SdfPathVector *paths, bool localOnly, const SdfSpecHandle &stopProperty, bool includeStopProperty, SdfPathVector *deletedPaths, PcpErrorVector *allErrors)
Definition: token.h:70
PCP_API const PcpPropertyIndex * FindPropertyIndex(const SdfPath &propPath) const
std::vector< class SdfPath > SdfPathVector
PCP_API size_t GetUsedLayersRevision() const
PCP_API void Apply(const PcpCacheChanges &changes, PcpLifeboat *lifeboat)
std::unordered_set< SdfPath, SdfPath::Hash > PayloadSet
Returns the payloads requested for inclusion.
Definition: cache.h:153
PCP_API PcpLayerStackRefPtr ComputeLayerStack(const PcpLayerStackIdentifier &identifier, PcpErrorVector *allErrors)
PCP_API void RequestPayloads(const SdfPathSet &pathsToInclude, const SdfPathSet &pathsToExclude, PcpChanges *changes=NULL)
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:440
PCP_API void ReloadReferences(PcpChanges *changes, const SdfPath &primPath)
friend class Pcp_Statistics
Definition: cache.h:616
PCP_API const PcpLayerStackPtrVector & FindAllLayerStacksUsingLayer(const SdfLayerHandle &layer) const
Returns every computed & cached layer stack that includes layer.
PCP_API bool IsInvalidSublayerIdentifier(const std::string &identifier) const
SDF_DECLARE_HANDLES(SdfSpec)
Definition: path.h:280
PCP_API PcpLayerStackPtr GetLayerStack() const
PCP_API const std::unordered_set< std::string > & GetExpressionVariablesFromLayerStackUsedByPrim(const SdfPath &primIndexPath, const PcpLayerStackPtr &layerStack) const
PCP_API PcpLayerStackPtr FindLayerStack(const PcpLayerStackIdentifier &identifier) const
PCP_API const PcpPrimIndexInputs & GetPrimIndexInputs() const
std::vector< PcpErrorBasePtr > PcpErrorVector
Definition: errors.h:65
PCP_API const PcpPrimIndex * FindPrimIndex(const SdfPath &primPath) const
PCP_API void SetVariantFallbacks(const PcpVariantFallbackMap &map, PcpChanges *changes=NULL)
std::set< class SdfPath > SdfPathSet
A set of SdfPaths.
Definition: path.h:199
PCP_API std::map< SdfPath, std::vector< std::string >, SdfPath::FastLessThan > GetInvalidAssetPaths() const
friend class Pcp_Dependencies
Definition: cache.h:615
TF_DECLARE_WEAK_AND_REF_PTRS(PcpLayerStack)
void ForEachPrimIndex(const Callback &callback) const
Definition: cache.h:335
PCP_API PcpVariantFallbackMap GetVariantFallbacks() const
PCP_API SdfLayerHandleSet GetUsedLayers() const
Returns set of all layers used by this cache.
GLuint index
Definition: glcorearb.h:786
bool HasRootLayerStack(PcpLayerStackRefPtr const &layerStack) const
Definition: cache.h:117
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
PCP_API const PcpLayerStackIdentifier & GetLayerStackIdentifier() const
Get the identifier of the layerStack used for composition.
PCP_API bool IsPossibleDynamicFileFormatArgumentField(const TfToken &field) const
void ComputePrimIndexesInParallel(const SdfPath &path, PcpErrorVector *allErrors, const ChildrenPredicate &childrenPred, const PayloadPredicate &payloadPred)
Definition: cache.h:305
PCP_API void RequestLayerMuting(const std::vector< std::string > &layersToMute, const std::vector< std::string > &layersToUnmute, PcpChanges *changes=nullptr, std::vector< std::string > *newLayersMuted=nullptr, std::vector< std::string > *newLayersUnmuted=nullptr)
void ForEachLayerStack(const Callback &callback) const
Definition: cache.h:422
PCP_API void ComputeRelationshipTargetPaths(const SdfPath &relationshipPath, SdfPathVector *paths, bool localOnly, const SdfSpecHandle &stopProperty, bool includeStopProperty, SdfPathVector *deletedPaths, PcpErrorVector *allErrors)
PCP_API bool IsPossibleDynamicFileFormatArgumentAttribute(const TfToken &attributeName) const
PCP_API PayloadSet const & GetIncludedPayloads() const
Returns the payloads requested for inclusion.
unsigned int PcpDependencyFlags
A typedef for a bitmask of flags from PcpDependencyType.
Definition: dependency.h:92
PCP_API void PrintStatistics() const
Prints various statistics about the data stored in this cache.
std::map< std::string, std::vector< std::string > > PcpVariantFallbackMap
Definition: types.h:189
PCP_API bool UsesLayerStack(const PcpLayerStackPtr &layerStack) const
int invoke(const Func &taskFunc1, Rest...taskFuncN)
Definition: Invoke.h:64
#define PCP_API
Definition: api.h:23