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