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 /// \file LayerStackRegistry.cpp
25 
26 #include "pxr/pxr.h"
27 #include "pxr/usd/pcp/layerStackRegistry.h"
28 #include "pxr/usd/pcp/layerStack.h"
29 #include "pxr/usd/pcp/layerStackIdentifier.h"
30 
31 #include "pxr/usd/ar/resolver.h"
32 #include "pxr/usd/sdf/layerUtils.h"
33 #include "pxr/base/tf/diagnostic.h"
34 #include "pxr/base/tf/staticData.h"
35 
36 #include <tbb/queuing_rw_mutex.h>
37 
38 #include <boost/unordered_map.hpp>
39 
40 #include <algorithm>
41 #include <utility>
42 
43 using std::pair;
44 using std::make_pair;
45 
46 PXR_NAMESPACE_OPEN_SCOPE
47 
48 class Pcp_LayerStackRegistryData {
49 public:
Pcp_LayerStackRegistryData(const std::string & fileFormatTarget_,bool isUsd)50     Pcp_LayerStackRegistryData(
51         const std::string& fileFormatTarget_, bool isUsd)
52         : fileFormatTarget(fileFormatTarget_)
53         , isUsd(isUsd)
54     { }
55 
56     typedef SdfLayerHandleVector Layers;
57     typedef PcpLayerStackPtrVector LayerStacks;
58     typedef boost::unordered_map<PcpLayerStackIdentifier, PcpLayerStackPtr>
59         IdentifierToLayerStack;
60     typedef boost::unordered_map<SdfLayerHandle, LayerStacks>
61         LayerToLayerStacks;
62     typedef boost::unordered_map<PcpLayerStackPtr, Layers>
63         LayerStackToLayers;
64 
65     typedef boost::unordered_map<std::string, LayerStacks>
66         MutedLayerIdentifierToLayerStacks;
67     typedef boost::unordered_map<PcpLayerStackPtr, std::set<std::string> >
68         LayerStackToMutedLayerIdentifiers;
69 
70     IdentifierToLayerStack identifierToLayerStack;
71     LayerToLayerStacks layerToLayerStacks;
72     LayerStackToLayers layerStackToLayers;
73     MutedLayerIdentifierToLayerStacks mutedLayerIdentifierToLayerStacks;
74     LayerStackToMutedLayerIdentifiers layerStackToMutedLayerIdentifiers;
75 
76     const PcpLayerStackPtrVector empty;
77     const std::string fileFormatTarget;
78     bool isUsd;
79     Pcp_MutedLayers mutedLayers;
80 
81     tbb::queuing_rw_mutex mutex;
82 };
83 
84 Pcp_LayerStackRegistryRefPtr
New(const std::string & fileFormatTarget,bool isUsd)85 Pcp_LayerStackRegistry::New(const std::string& fileFormatTarget, bool isUsd)
86 {
87     return TfCreateRefPtr(new Pcp_LayerStackRegistry(fileFormatTarget, isUsd));
88 }
89 
Pcp_LayerStackRegistry(const std::string & fileFormatTarget,bool isUsd)90 Pcp_LayerStackRegistry::Pcp_LayerStackRegistry(
91     const std::string& fileFormatTarget, bool isUsd)
92     : _data(new Pcp_LayerStackRegistryData(fileFormatTarget, isUsd))
93 {
94     // Do nothing
95 }
96 
~Pcp_LayerStackRegistry()97 Pcp_LayerStackRegistry::~Pcp_LayerStackRegistry()
98 {
99     // Do nothing
100 }
101 
102 void
MuteAndUnmuteLayers(const SdfLayerHandle & anchorLayer,std::vector<std::string> * layersToMute,std::vector<std::string> * layersToUnmute)103 Pcp_LayerStackRegistry::MuteAndUnmuteLayers(
104     const SdfLayerHandle& anchorLayer,
105     std::vector<std::string>* layersToMute,
106     std::vector<std::string>* layersToUnmute)
107 {
108     _data->mutedLayers.MuteAndUnmuteLayers(
109         anchorLayer, layersToMute, layersToUnmute);
110 }
111 
112 const std::vector<std::string>&
GetMutedLayers() const113 Pcp_LayerStackRegistry::GetMutedLayers() const
114 {
115     return _data->mutedLayers.GetMutedLayers();
116 }
117 
118 bool
IsLayerMuted(const SdfLayerHandle & anchorLayer,const std::string & layerIdentifier,std::string * canonicalSublayerId) const119 Pcp_LayerStackRegistry::IsLayerMuted(const SdfLayerHandle& anchorLayer,
120                                      const std::string& layerIdentifier,
121                                      std::string* canonicalSublayerId) const
122 {
123     return _data->mutedLayers.IsLayerMuted(
124         anchorLayer, layerIdentifier, canonicalSublayerId);
125 }
126 
127 const PcpLayerStackPtrVector&
FindAllUsingMutedLayer(const std::string & layerId) const128 Pcp_LayerStackRegistry::FindAllUsingMutedLayer(const std::string& layerId) const
129 {
130     tbb::queuing_rw_mutex::scoped_lock lock(_data->mutex, /*write=*/false);
131     const auto i = _data->mutedLayerIdentifierToLayerStacks.find(layerId);
132     return i != _data->mutedLayerIdentifierToLayerStacks.end() ?
133         i->second : _data->empty;
134 }
135 
136 PcpLayerStackRefPtr
FindOrCreate(const PcpLayerStackIdentifier & identifier,PcpErrorVector * allErrors)137 Pcp_LayerStackRegistry::FindOrCreate(const PcpLayerStackIdentifier& identifier,
138                                      PcpErrorVector *allErrors)
139 {
140     // Can only create layer stacks for valid identifiers so if the identifier
141     // is invalid we can't have an entry for it.
142     if (!identifier) {
143         TF_CODING_ERROR("Cannot build layer stack with null rootLayer");
144         return TfNullPtr;
145     }
146 
147     tbb::queuing_rw_mutex::scoped_lock lock(_data->mutex, /*write=*/false);
148     PcpLayerStackRefPtr refLayerStack;
149 
150     if (const PcpLayerStackPtr & layerStack = _Find(identifier)) {
151         refLayerStack = TfCreateRefPtrFromProtectedWeakPtr(layerStack);
152     }
153     if (!refLayerStack) {
154         lock.release();
155 
156         PcpLayerStackRefPtr createdLayerStack =
157             TfCreateRefPtr(new PcpLayerStack(
158                 identifier, _GetFileFormatTarget(), _GetMutedLayers(),
159                 _IsUsd()));
160 
161         // Take the lock and check again for an existing layer stack, or
162         // install the one we just created.
163         lock.acquire(_data->mutex);
164         if (const PcpLayerStackPtr & layerStack = _Find(identifier)) {
165             refLayerStack = TfCreateRefPtrFromProtectedWeakPtr(layerStack);
166         }
167         if (!refLayerStack) {
168             // No existing entry, or it is being deleted. Add the one we just
169             // create to the map.
170             refLayerStack = createdLayerStack;
171             _data->identifierToLayerStack[identifier] = refLayerStack;
172             // Also give it a link back to us so it can remove itself upon
173             // destruction, and install its layers into our structures.
174             refLayerStack->_registry = TfCreateWeakPtr(this);
175             _SetLayers(get_pointer(refLayerStack));
176             lock.release();
177 
178             // Return errors from newly computed layer stacks.
179             PcpErrorVector errors = refLayerStack->GetLocalErrors();
180             allErrors->insert(allErrors->end(), errors.begin(), errors.end());
181         }
182     }
183 
184     return refLayerStack;
185 }
186 
187 PcpLayerStackPtr
Find(const PcpLayerStackIdentifier & identifier) const188 Pcp_LayerStackRegistry::Find(const PcpLayerStackIdentifier& identifier) const
189 {
190     tbb::queuing_rw_mutex::scoped_lock lock(_data->mutex, /*write=*/false);
191     return _Find(identifier);
192 }
193 
194 PcpLayerStackPtr
_Find(const PcpLayerStackIdentifier & identifier) const195 Pcp_LayerStackRegistry::_Find(const PcpLayerStackIdentifier& identifier) const
196 {
197     auto iter = _data->identifierToLayerStack.find(identifier);
198     return (iter != _data->identifierToLayerStack.end()) ?
199         iter->second : PcpLayerStackPtr();
200 }
201 
202 bool
Contains(const PcpLayerStackPtr & layerStack) const203 Pcp_LayerStackRegistry::Contains(const PcpLayerStackPtr& layerStack) const
204 {
205     auto ptr = get_pointer(layerStack);
206     return ptr && get_pointer(ptr->_registry) == this;
207 }
208 
209 const PcpLayerStackPtrVector&
FindAllUsingLayer(const SdfLayerHandle & layer) const210 Pcp_LayerStackRegistry::FindAllUsingLayer(const SdfLayerHandle& layer) const
211 {
212     tbb::queuing_rw_mutex::scoped_lock lock(_data->mutex, /*write=*/false);
213     auto i = _data->layerToLayerStacks.find(layer);
214     return i != _data->layerToLayerStacks.end() ? i->second : _data->empty;
215 }
216 
217 std::vector<PcpLayerStackPtr>
GetAllLayerStacks() const218 Pcp_LayerStackRegistry::GetAllLayerStacks() const
219 {
220     tbb::queuing_rw_mutex::scoped_lock lock(_data->mutex, /*write=*/false);
221     std::vector<PcpLayerStackPtr> result;
222     result.reserve(_data->identifierToLayerStack.size());
223     TF_FOR_ALL(i, _data->identifierToLayerStack) {
224         TF_VERIFY(i->second, "Unexpected dead layer stack %s",
225                   TfStringify(i->first).c_str());
226         result.push_back(i->second);
227     }
228     return result;
229 }
230 
231 void
ForEachLayerStack(const TfFunctionRef<void (const PcpLayerStackPtr &)> & fn)232 Pcp_LayerStackRegistry::ForEachLayerStack(
233     const TfFunctionRef<void(const PcpLayerStackPtr&)>& fn)
234 {
235     // Copy all layer stacks so that we can run the callback
236     // without holding a read lock on the layer registry.
237     const std::vector<PcpLayerStackPtr> layerStacks = GetAllLayerStacks();
238     for (const PcpLayerStackPtr& layerStack : layerStacks) {
239         fn(layerStack);
240     }
241 }
242 
243 ////////////////////////////////////////////////////////////////////////
244 // Private helper methods.
245 
246 void
_SetLayersAndRemove(const PcpLayerStackIdentifier & identifier,const PcpLayerStack * layerStack)247 Pcp_LayerStackRegistry::_SetLayersAndRemove(
248     const PcpLayerStackIdentifier& identifier,
249     const PcpLayerStack *layerStack)
250 {
251     tbb::queuing_rw_mutex::scoped_lock lock(_data->mutex, /*write=*/true);
252 
253     Pcp_LayerStackRegistryData::IdentifierToLayerStack::const_iterator i =
254         _data->identifierToLayerStack.find(identifier);
255     // It's possible that layerStack has already been removed from the
256     // map if a FindOrCreate call intercedes between the moment when the
257     // layer stack's ref count drops to zero and the time the layer stack
258     // destructor is called (which is how we get into this method).
259     // Always call _SetLayers to clear this (now empty) layer stack's
260     // pointer from the maps inside _data, even if a new layer stack with the
261     // same identifier has already been added to the identifierToLayerStack
262     // map.
263     _SetLayers(layerStack);
264     if (i != _data->identifierToLayerStack.end() &&
265         i->second.operator->() == layerStack) {
266         _data->identifierToLayerStack.erase(identifier);
267     }
268 }
269 
270 void
_SetLayers(const PcpLayerStack * layerStack)271 Pcp_LayerStackRegistry::_SetLayers(const PcpLayerStack* layerStack)
272 {
273     PcpLayerStackPtr layerStackPtr = TfCreateNonConstWeakPtr(layerStack);
274 
275     // Get the layers for the layer stack.
276     Pcp_LayerStackRegistryData::Layers& layers =
277         _data->layerStackToLayers[layerStackPtr];
278 
279     // Remove layer stack from the table entry for each layer in
280     // the layer stack.
281     for (const auto& layer : layers) {
282         Pcp_LayerStackRegistryData::LayerStacks& layerStacks =
283             _data->layerToLayerStacks[layer];
284         layerStacks.erase(std::find(layerStacks.begin(),
285                                     layerStacks.end(), layerStackPtr));
286     }
287 
288     // Save the layers for the layer stack.
289     const SdfLayerRefPtrVector& newLayers = layerStack->GetLayers();
290     if (newLayers.empty()) {
291         // Don't leave empty entries hanging around.
292         _data->layerStackToLayers.erase(layerStackPtr);
293     } else {
294         layers.assign(newLayers.begin(), newLayers.end());
295     }
296 
297     // Add the layer stack for each layer in the layer stack.
298     for (const auto& layer : newLayers) {
299         _data->layerToLayerStacks[layer].push_back(layerStackPtr);
300     }
301 
302     // Also store mappings from layer stack <-> muted layers in
303     // the layer stack.
304     std::set<std::string>* mutedLayerIdentifiers = TfMapLookupPtr(
305         _data->layerStackToMutedLayerIdentifiers, layerStackPtr);
306 
307     if (mutedLayerIdentifiers) {
308         for (const auto& layerId : *mutedLayerIdentifiers) {
309             Pcp_LayerStackRegistryData::LayerStacks& layerStacks =
310                 _data->mutedLayerIdentifierToLayerStacks[layerId];
311             layerStacks.erase(std::find(layerStacks.begin(),
312                                         layerStacks.end(), layerStackPtr));
313         }
314     }
315 
316     const std::set<std::string>& newMutedLayers = layerStack->GetMutedLayers();
317     if (newMutedLayers.empty()) {
318         if (mutedLayerIdentifiers) {
319             // Don't leave empty entries hanging around.
320             _data->layerStackToMutedLayerIdentifiers.erase(layerStackPtr);
321         }
322     }
323     else {
324         if (!mutedLayerIdentifiers) {
325             mutedLayerIdentifiers =
326                 &_data->layerStackToMutedLayerIdentifiers[layerStackPtr];
327         }
328         *mutedLayerIdentifiers = std::set<std::string>(
329             newMutedLayers.begin(), newMutedLayers.end());
330     }
331 
332     for (const auto& mutedLayer : newMutedLayers) {
333         _data->mutedLayerIdentifierToLayerStacks[mutedLayer]
334             .push_back(layerStackPtr);
335     }
336 }
337 
338 const std::string&
_GetFileFormatTarget() const339 Pcp_LayerStackRegistry::_GetFileFormatTarget() const
340 {
341     return _data->fileFormatTarget;
342 }
343 
344 bool
_IsUsd() const345 Pcp_LayerStackRegistry::_IsUsd() const
346 {
347     return _data->isUsd;
348 }
349 
350 const Pcp_MutedLayers&
_GetMutedLayers() const351 Pcp_LayerStackRegistry::_GetMutedLayers() const
352 {
353     return _data->mutedLayers;
354 }
355 
356 // ------------------------------------------------------------
357 
358 namespace
359 {
360 std::string
_GetCanonicalLayerId(const SdfLayerHandle & anchorLayer,const std::string & layerId)361 _GetCanonicalLayerId(const SdfLayerHandle& anchorLayer,
362                      const std::string& layerId)
363 {
364 #if AR_VERSION == 1
365     const std::string computedLayerId =
366         SdfComputeAssetPathRelativeToLayer(anchorLayer, layerId);
367     if (computedLayerId.empty()) {
368         return layerId;
369     }
370 
371     if (SdfLayer::IsAnonymousLayerIdentifier(computedLayerId)) {
372         return computedLayerId;
373     }
374 
375     ArResolver& resolver = ArGetResolver();
376 
377     std::string canonicalPath = computedLayerId;
378     if (resolver.IsSearchPath(canonicalPath)) {
379         std::string resolvedSearchPath = resolver.Resolve(canonicalPath);
380         if (!resolvedSearchPath.empty()) {
381             canonicalPath.swap(resolvedSearchPath);
382         }
383     }
384 
385     canonicalPath = resolver.ComputeRepositoryPath(canonicalPath);
386     return canonicalPath.empty() ? computedLayerId : canonicalPath;
387 #else
388     if (SdfLayer::IsAnonymousLayerIdentifier(layerId)) {
389         return layerId;
390     }
391 
392     // XXX:
393     // We may ultimately want to use the resolved path here but that's
394     // possibly a bigger change and there are questions about what happens if
395     // the muted path doesn't resolve to an existing asset and how/when to
396     // invalidate the resolved paths stored in the Pcp_MutedLayers object.
397     return ArGetResolver().CreateIdentifier(
398         layerId, anchorLayer->GetResolvedPath());
399 #endif
400 }
401 }
402 
403 const std::vector<std::string>&
GetMutedLayers() const404 Pcp_MutedLayers::GetMutedLayers() const
405 {
406     return _layers;
407 }
408 
409 void
MuteAndUnmuteLayers(const SdfLayerHandle & anchorLayer,std::vector<std::string> * layersToMute,std::vector<std::string> * layersToUnmute)410 Pcp_MutedLayers::MuteAndUnmuteLayers(const SdfLayerHandle& anchorLayer,
411                                      std::vector<std::string>* layersToMute,
412                                      std::vector<std::string>* layersToUnmute)
413 {
414     std::vector<std::string> mutedLayers, unmutedLayers;
415 
416     for (const auto& layerToMute : *layersToMute) {
417         const std::string canonicalId =
418             _GetCanonicalLayerId(anchorLayer, layerToMute);
419 
420         const auto layerIt = std::lower_bound(
421             _layers.begin(), _layers.end(), canonicalId);
422         if (layerIt == _layers.end() || *layerIt != canonicalId) {
423             _layers.insert(layerIt, canonicalId);
424             mutedLayers.push_back(canonicalId);
425         }
426     }
427 
428     for (const auto& layerToUnmute : *layersToUnmute) {
429         const std::string canonicalId =
430             _GetCanonicalLayerId(anchorLayer, layerToUnmute);
431 
432         const auto layerIt = std::lower_bound(
433             _layers.begin(), _layers.end(), canonicalId);
434         if (layerIt != _layers.end() && *layerIt == canonicalId) {
435             _layers.erase(layerIt);
436             unmutedLayers.push_back(canonicalId);
437         }
438     }
439 
440     layersToMute->swap(mutedLayers);
441     layersToUnmute->swap(unmutedLayers);
442 }
443 
444 bool
IsLayerMuted(const SdfLayerHandle & anchorLayer,const std::string & layerId,std::string * canonicalLayerId) const445 Pcp_MutedLayers::IsLayerMuted(const SdfLayerHandle& anchorLayer,
446                               const std::string& layerId,
447                               std::string* canonicalLayerId) const
448 {
449     if (_layers.empty()) {
450         return false;
451     }
452 
453     std::string canonicalId = _GetCanonicalLayerId(anchorLayer, layerId);
454     if (std::binary_search(_layers.begin(), _layers.end(), canonicalId)) {
455         if (canonicalLayerId) {
456             canonicalLayerId->swap(canonicalId);
457         }
458         return true;
459     }
460     return false;
461 }
462 
463 PXR_NAMESPACE_CLOSE_SCOPE
464