HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
stageCache.h
Go to the documentation of this file.
1 //
2 // Copyright 2017 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 _GUSD_STAGECACHE_H_
25 #define _GUSD_STAGECACHE_H_
26 
27 #include <UT/UT_Array.h>
28 #include <UT/UT_Error.h>
29 #include <UT/UT_Set.h>
30 
31 #include "gusd/defaultArray.h"
32 #include "gusd/stageEdit.h"
33 #include "gusd/stageOpts.h"
34 #include "gusd/USD_Utils.h"
35 
36 #include "pxr/pxr.h"
37 #include "pxr/usd/sdf/layer.h"
38 #include "pxr/usd/usd/stage.h"
39 
40 class OP_Node;
41 class DEP_MicroNode;
42 class UT_Options;
43 class UT_StringHolder;
44 class UT_StringSet;
45 class UT_StringRef;
46 
48 
50 typedef void (*GusdStageCacheReaderTracker)(bool addreader);
51 
52 class GusdUSD_DataCache;
53 class UsdPrim;
54 
55 /// Cache for USD stages.
56 /// Clients interact with the cache via the GusdStageCacheReader
57 /// and GusdStageCacheWriter classes.
59 {
60 public:
62 
63  ~GusdStageCache();
64 
65  GusdStageCache(const GusdStageCache&) = delete;
66 
67  GusdStageCache& operator=(const GusdStageCache&) = delete;
68 
69  /// Get the singleton GusdStageCache object.
70  static GusdStageCache& GetInstance();
71 
72  /// Set the callback function that should be used to interpret stage
73  /// file paths that specify a LOP node.
74  static void SetLopStageResolver(GusdLopStageResolver resolver);
75 
76  /// Set a callback used to track the construction and destruction of
77  /// stage cache readers/writers. This is used by the Lop Stage Resolver
78  /// to know when it is safe to clean up after itself.
79  static void SetStageCacheReaderTracker(GusdStageCacheReaderTracker tracker);
80 
81  /// Utility function to create a LOP stage identifier from a path to a
82  /// LOP node, and the other bits of data required to generated a locked
83  /// stage from a LOP node in the HUSD library.
84  static UT_StringHolder CreateLopStageIdentifier(OP_Node *lop,
85  int output_index,
86  bool strip_layers,
87  fpreal t,
88  const UT_Options &opts);
89  /// Utility function to split a stage file path specifying a LOP node
90  /// into a part that specifies the LOP node and any additional arguments
91  /// that may appear after the LOP node path. Returns true if the path is
92  /// a LOP node path (starts with "op:"), otherwise returns false.
93  static bool SplitLopStageIdentifier(const UT_StringRef &identifier,
94  OP_Node *&lop,
95  int &output_index,
96  bool &strip_layers,
97  fpreal &t,
98  UT_Options &opts);
99 
100  /// Add/remove auxiliary data caches.
101  /// Auxiliary data caches are cleared in response to changes
102  /// to stages on this cache.
103  /// @{
104  void AddDataCache(GusdUSD_DataCache& cache);
105 
106  void RemoveDataCache(GusdUSD_DataCache& cache);
107  /// @}
108 
109  /// \section GusdStageCache_Reloading Reloading
110  ///
111  /// Stages and layers may be reloaded during an active session, but it's
112  /// important to understand the full implications of doing so.
113  /// When a layer is reloaded, change notifications are sent to any stages
114  /// referencing that layer, causing those stages to recompose, if necessary.
115  /// This operation is not thread-safe, and may result in a crash if another
116  /// thread is attempting to read from an affected stage at the same time.
117  /// Further, it must be noted that simply loading stages within separate
118  /// GusdStageCache instances also does not mean that that change
119  /// propopagation will be isolated only to stages of the stage cache
120  /// instance: Although it is possible to isolate the effect of changes
121  /// on the root layers of stages to some extent, secondary layers -- such
122  /// as sublayers and reference arcs -- are shared on a global cache.
123  /// The effect of reloading layers is _global_ and _immediate_.
124  ///
125  /// Rather than attempting to solve this problem with intrusive and
126  /// expensive locking -- which would only solve the problem for stages
127  /// held internally in a GusdStageCache, not for stages referenced from
128  /// other caches -- we prefer to address the problem by requiring that
129  /// reloading only be performed at certain points of Houdini's main event
130  /// loop, where it is known to be safe.
131  /// An example of a 'safe' way to exec stage reloads is via a callback
132  /// triggered by a button in a node's GUI.
133  /// Users should never attempt to reload stages or layers during node
134  /// cook methods.
135 
136  /// Mark a set of stages for reload on the event queue.
137  static void ReloadStages(const UT_Set<UsdStagePtr>& stages);
138 
139  /// Mark a set of layers for reload on the event queue.
140  static void ReloadLayers(const UT_Set<SdfLayerHandle>& layers);
141 
142 
143 private:
144  class _MaskedStageCache;
145 
146  class _Impl;
147  _Impl* const _impl;
148 
149  friend class GusdStageCacheReader;
150  friend class GusdStageCacheWriter;
151 };
152 
153 
154 /// Helper for reading from a GusdStageCache.
155 /// Cache readers can both open existing stages on the cache,
156 /// as well as cause additional stages to be inserted into the cache.
157 /// Cache readers cannot clear out any existing stages or mutate
158 /// auxiliary data caches.
159 ///
160 /// Example usage:
161 /// @code
162 /// GusdStageCacheReader cache;
163 ///
164 /// // Pull a stage from the cache.
165 /// UsdStageRefPtr stage = cache.FindOrOpen(stagePath);
166 ///
167 /// // Access a prim on the cache.
168 /// UsdPrim prim = cache.GetPrim(stagePath, primPath).first;
169 ///
170 /// // Access a prim with a variant selection.
171 /// SdfPath primPath("/foo{variant=sel}bar");
172 /// UsdPrim prim = cache.GetPrim(stagePath, primPath);
173 /// @endcode
175 {
176 public:
177  using PrimStagePair = std::pair<UsdPrim,UsdStageRefPtr>;
178 
179  /// Construct a reader for the cache singleton.
181  : GusdStageCacheReader(cache, false) {}
182 
184 
186 
188 
189  /// Find an existing stage on the cache.
190  UsdStageRefPtr
191  Find(const UT_StringRef& path,
193  const GusdStageEditPtr& edit=nullptr) const;
194 
195  /// Return a stage from the cache, if one exists.
196  /// If not, attempt to open the stage and add it to the cache.
197  /// If \p path is a non-empty path and stage opening fails, errors
198  /// are reporting to the currently scoped error manager at a severity
199  /// of \p sev.
200  UsdStageRefPtr
201  FindOrOpen(const UT_StringRef& path,
203  const GusdStageEditPtr& edit=nullptr,
205 
206  /// Insert a stage into our cache. The lifetime of this stage is not
207  /// fully controlled by this cache. The cache is just a holder for the
208  /// stage for as long as the gusd library is allowed access to it until
209  /// it is destroyed by the external owner, which must then call Clear()
210  /// with the same path.
211  void
212  InsertStage(UsdStageRefPtr &stage,
213  const UT_StringRef& path,
214  const GusdStageOpts& opts,
215  const GusdStageEditPtr& edit);
216 
217  /// Get a micro node for a stage.
218  /// Micro nodes are created on demand, and are dirtied both for
219  /// stage reloading and cache evictions.
221  GetStageMicroNode(const UsdStagePtr& stage);
222 
223  /// \section Prim Accessors
224  ///
225  /// These helpers return prims on masked stages, where only the
226  /// parts of the stage required to produce a given prim are composed.
227  /// This helps support workflows such as setting variants on packed prims,
228  /// where either many stage mutations may be made that conflict with each
229  /// other, or in isolation, such that different mutations can't be made
230  /// to share stages without intrusive locking.
231  /// In all cases, if a full stage which satisfies the stage options and
232  /// edits has already been loaded on the cache, the prim will fetched from
233  /// that stage instead.
234  ///
235  /// This use of masking may be disabled by way of the GUSD_STAGEMASK_ENABLE
236  /// environment variable, but beware that doing so may significantly degrade
237  /// performance for certain access patterns, such as if many separate prims
238  /// are being queried from the cache with different stage edits.
239  ///
240  /// \subsection Primitive Encapsulation
241  ///
242  /// Because primitives are masked to include a subset of a stage,
243  /// there is an expectation that the caller follows _encapsulation_ rules.
244  /// When we read in a prim, we consider that prim to be encapsulated,
245  /// which means that if any other primitives from the stage are required
246  /// to process an encapsulated primitive, they are expected to either
247  /// be descendants or ancestors of the encapsulated prim, or the dependency
248  /// to that external prim must be discoverable using either relationships
249  /// or attribute connections.
250  /// Following those encapsulation rules, neither _siblings_ of the prim
251  /// being requested, nor other prims in separate branches of the stage
252  /// are guaranteed to be loaded. Any attempt to reach other prims that
253  /// can't be discovered using the above rules for discovering dependencies
254  /// may either fail or introduce non-deterministic behavior.
255 
256  /// Get a prim from the cache, on a masked stage.
257  /// If \p path and \p primPath are both valid, and either a stage load
258  /// error occurs or no prim can be found, errors are reported on the
259  /// currently scoped error manager at a severity of \p sev.
260  /// If \p primPath is equal to 'defaultPrim', the stage's defaultPrim
261  /// is returned.
262  /// If \p primPath is equal to '/', the entire stage is loaded,
263  /// and the pseudo-root is returned.
264  PrimStagePair
265  GetPrim(const UT_StringRef& path,
266  const SdfPath& primPath,
267  const GusdStageEditPtr& stageEdit=GusdStageEditPtr(),
270 
271  /// Get multiple prims from the cache (in parallel).
272  /// If the configured error severity is less than UT_ERROR_ABORT,
273  /// prim loading will continue even after load errors have occurred.
274  /// If any stage load errors occur, or if any prims cannot be found, errors
275  /// are reported on the currently scoped error manager with a severity of
276  /// \p sev. If \p sev is less than UT_ERROR_ABORT, prim loading will
277  /// continue even when errors occur for some prims. Otherwise, loading
278  /// aborts upon the first error.
279  /// If a path in \p primPaths is equal to `defaultPrim`, the stage's
280  /// defaultPrim will be returned for that element.
281  /// If a path in \p primPaths is equal to `/` -- I.e., the absolute root --
282  /// then the full stage of the corresponding element is loaded, and the
283  /// pseudo-root is returned.
284  bool
285  GetPrims(const GusdDefaultArray<UT_StringHolder>& filePaths,
286  const UT_Array<SdfPath>& primPaths,
288  UsdPrim* prims,
291 
292  /// Get a prim from the cache, given a prim path that may contain
293  /// variant selections. This is a convenience method for the common case
294  /// of accessing a prim given parameters for just a file path and
295  /// prim path.
296  /// If \p primPath is equal to 'defaultPrim', the stage's defaultPrim
297  /// is returned.
298  /// If \p primPath is equal to `/`, the entire stage is loaded,
299  /// and the pseudo-root is returned.
300  /// @{
301  PrimStagePair
302  GetPrimWithVariants(const UT_StringRef& path,
303  const SdfPath& primPath,
306 
307  PrimStagePair
308  GetPrimWithVariants(const UT_StringRef& path,
309  const UT_StringRef& primPath,
312 
313  /// Different variations of the above the variants are stored separately.
314  PrimStagePair
315  GetPrimWithVariants(const UT_StringRef& path,
316  const SdfPath& primPath,
317  const SdfPath& variants,
320 
321  PrimStagePair
322  GetPrimWithVariants(const UT_StringRef& path,
323  const UT_StringRef& primPath,
324  const UT_StringRef& variants,
327  /// @}
328 
329 protected:
330  GusdStageCacheReader(GusdStageCache& cache, bool writer);
331 
332 protected:
334  const bool _writer;
335 };
336 
337 
338 /// Write accessor for a stage cache.
339 /// Write accessors have all of the capabilities of readers,
340 /// and can also remove elements from the cache and manipulate
341 /// child data caches.
342 /// Writers gain exclusive locks to the cache, and should be used sparingly.
344 {
345 public:
347 
349 
351 
352  /// Find all stages on the cache matching the given paths.
353  /// Multiple stages may be found for each path.
354  void FindStages(const UT_StringSet& paths,
356 
357  /// \section GusdStageCacheWriter_ReloadAndClear Reloading And Clearing
358  ///
359  /// During active sessions, the contents of a cache may be refreshed
360  /// by either reloading a subset of the stages that it contains, or by
361  /// removing stage entries from the cache.
362  /// In either case, if a stage is reloaded or evicted from the cache,
363  /// and if that stage has a micro node
364  /// (see: \ref GusdStageCacheReader::GetMicroNode), then that micro
365  /// node, and any OP_Node instances that reference it, are dirtied.
366  /// This means that any nodes whose cook is based on data from a cached
367  /// stage will properly update in response to Clear()/Reload() actions.
368  ///
369  /// \warn Dirty state propagation is not thread safe, and should only be
370  /// called at a safe point on the main thread, such as through a callback
371  /// triggered by a UI button. Also note that there may be side effects
372  /// from reloading stages that affect stages from *other caches*. See
373  /// \ref GusdStageCache_Reloading for more information on the caveats of
374  /// reloading.
375 
376  /// Clear out all cached items.
377  /// Note that layers are owned by a different cache, and may stay
378  /// active beyond this point.
379  void Clear();
380 
381  /// Variant of Clear() that does not remove cached stages from LOPs.
382  /// Returns the number of entries that were removed.
383  exint ClearEntriesFromDisk();
384 
385  /// Variant of Clear() that causes any stages whose root layer has
386  /// an asset path in the \p paths set to be removed from the cache.
387  void Clear(const UT_StringSet& paths);
388 
389  /// Reload all stages matching the given paths.
390  void ReloadStages(const UT_StringSet& paths);
391 };
392 
393 
395 
396 
397 #endif /*_GUSD_STAGECACHE_H_*/
PXR_NAMESPACE_OPEN_SCOPE typedef UT_StringHolder(* GusdLopStageResolver)(const UT_StringRef &path)
Definition: stageCache.h:49
Definition: UT_Set.h:58
GLbitfield stages
Definition: glcorearb.h:1931
void
Definition: png.h:1083
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
int64 exint
Definition: SYS_Types.h:125
UT_ErrorSeverity
Definition: UT_Error.h:25
void(* GusdStageCacheReaderTracker)(bool addreader)
Definition: stageCache.h:50
static GusdStageCache & GetInstance()
Get the singleton GusdStageCache object.
const bool _writer
Definition: stageCache.h:334
GusdStageCacheReader & operator=(const GusdStageCacheReader &)=delete
static GusdStageOpts LoadAll()
Return options that a configure a stage to be loaded with payloads.
Definition: stageOpts.h:52
UT_IntrusivePtr< class GusdStageEdit > GusdStageEditPtr
Definition: stageEdit.h:42
Wrapper around hboost::intrusive_ptr.
Definition: prim.h:116
Definition: path.h:273
GLdouble t
Definition: glad.h:2397
std::pair< UsdPrim, UsdStageRefPtr > PrimStagePair
Definition: stageCache.h:177
GusdStageCacheReader(GusdStageCache &cache=GusdStageCache::GetInstance())
Construct a reader for the cache singleton.
Definition: stageCache.h:180
A map of string to various well defined value types.
Definition: UT_Options.h:87
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
GusdStageCache & _cache
Definition: stageCache.h:333
fpreal64 fpreal
Definition: SYS_Types.h:278
LeafData & operator=(const LeafData &)=delete
friend class UT_StringHolder
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
#define GUSD_API
Definition: api.h:42