[dali_2.2.16] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / common / model-cache-manager.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-scene3d/internal/common/model-cache-manager.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/common/singleton-service.h>
23 #include <dali/public-api/object/base-object.h>
24 #include <unordered_map>
25
26 // INTERNAL INCLUDES
27 #include <dali-scene3d/public-api/loader/load-result.h>
28 #include <dali-scene3d/public-api/loader/scene-definition.h>
29
30 namespace Dali::Scene3D::Internal
31 {
32 class ModelCacheManager::Impl : public Dali::BaseObject
33 {
34 public:
35   /**
36    * @brief Constructor
37    */
38   Impl()
39   {
40   }
41
42   Dali::Scene3D::Loader::LoadResult GetModelLoadResult(std::string modelUri)
43   {
44     ModelCache& cache = mModelCache[modelUri];
45     return Dali::Scene3D::Loader::LoadResult{cache.resources, cache.scene, cache.metaData, cache.animationDefinitions, cache.amimationGroupDefinitions, cache.cameraParameters, cache.lights};
46   }
47
48   uint32_t GetModelCacheRefCount(std::string modelUri)
49   {
50     ModelCache& cache = mModelCache[modelUri];
51     return cache.refCount;
52   }
53
54   Dali::ConditionalWait& GetLoadSceneConditionalWaitInstance(std::string modelUri)
55   {
56     ModelCache& cache = mModelCache[modelUri];
57     return cache.loadSceneConditionalWait;
58   }
59
60   Dali::ConditionalWait& GetLoadRawResourceConditionalWaitInstance(std::string modelUri)
61   {
62     ModelCache& cache = mModelCache[modelUri];
63     return cache.loadRawResourceConditionalWait;
64   }
65
66   void ReferenceModelCache(std::string modelUri)
67   {
68     ModelCache& cache = mModelCache[modelUri];
69     cache.refCount++;
70   }
71
72   void UnreferenceModelCache(std::string modelUri)
73   {
74     ModelCache& cache = mModelCache[modelUri];
75     if(cache.refCount > 0)
76     {
77       cache.refCount--;
78     }
79
80     if(cache.refCount == 0)
81     {
82       mModelCache.erase(modelUri);
83     }
84   }
85
86   bool IsSceneLoaded(std::string modelUri)
87   {
88     ModelCache& cache = mModelCache[modelUri];
89     return cache.isSceneLoaded;
90   }
91
92   void SetSceneLoaded(std::string modelUri, bool isSceneLoaded)
93   {
94     ModelCache& cache   = mModelCache[modelUri];
95     cache.isSceneLoaded = isSceneLoaded;
96   }
97
98   bool IsSceneLoading(std::string modelUri)
99   {
100     ModelCache& cache = mModelCache[modelUri];
101     return cache.isSceneLoading;
102   }
103
104   void SetSceneLoading(std::string modelUri, bool isSceneLoading)
105   {
106     ModelCache& cache    = mModelCache[modelUri];
107     cache.isSceneLoading = isSceneLoading;
108   }
109
110 protected:
111   /**
112    * A reference counted object may only be deleted by calling Unreference()
113    */
114   virtual ~Impl()
115   {
116   }
117
118 private:
119   struct ModelCache
120   {
121     Dali::Scene3D::Loader::ResourceBundle  resources{}; ///< The bundle to store resources in.
122     Dali::Scene3D::Loader::SceneDefinition scene{};     ///< The scene definition to populate.
123     Dali::Scene3D::Loader::SceneMetadata   metaData{};  ///< The metadata of the scene.
124
125     std::vector<Dali::Scene3D::Loader::AnimationDefinition>      animationDefinitions{};      ///< The list of animation definitions, in lexicographical order of their names.
126     std::vector<Dali::Scene3D::Loader::AnimationGroupDefinition> amimationGroupDefinitions{}; ///< The list of animation group definitions, in lexicographical order of their names.
127     std::vector<Dali::Scene3D::Loader::CameraParameters>         cameraParameters{};          ///< The camera parameters that were loaded from the scene.
128     std::vector<Dali::Scene3D::Loader::LightParameters>          lights{};                    ///< The light parameters that were loaded from the scene.
129
130     uint32_t              refCount{0};                      ///< The reference count of this model cache.
131     Dali::ConditionalWait loadSceneConditionalWait{};       ///< The conditionalWait instance used to synchronise the loading of the scene for the same model in different threads.
132     Dali::ConditionalWait loadRawResourceConditionalWait{}; ///< The conditionalWait instance used to synchronise the loading of the shared raw resources for the same model in different threads.
133
134     bool isSceneLoaded{false};  ///< Whether the scene of the model has been loaded.
135     bool isSceneLoading{false}; ///< Whether the scene loading of the model is in progress.
136   };
137
138   using ModelResourceCache = std::unordered_map<std::string, ModelCache>;
139   ModelResourceCache mModelCache;
140 };
141
142 ModelCacheManager::ModelCacheManager() = default;
143
144 ModelCacheManager::~ModelCacheManager() = default;
145
146 ModelCacheManager ModelCacheManager::Get()
147 {
148   ModelCacheManager manager;
149
150   // Check whether the ModelCacheManager is already created
151   SingletonService singletonService(SingletonService::Get());
152   if(singletonService)
153   {
154     Dali::BaseHandle handle = singletonService.GetSingleton(typeid(ModelCacheManager));
155     if(handle)
156     {
157       // If so, downcast the handle of singleton to ModelCacheManager
158       manager = ModelCacheManager(dynamic_cast<ModelCacheManager::Impl*>(handle.GetObjectPtr()));
159     }
160
161     if(!manager)
162     {
163       // If not, create the ModelCacheManager and register it as a singleton
164       manager = ModelCacheManager(new ModelCacheManager::Impl());
165       singletonService.Register(typeid(manager), manager);
166     }
167   }
168
169   return manager;
170 }
171
172 ModelCacheManager::ModelCacheManager(ModelCacheManager::Impl* impl)
173 : BaseHandle(impl)
174 {
175 }
176
177 Dali::Scene3D::Loader::LoadResult ModelCacheManager::GetModelLoadResult(std::string modelUri)
178 {
179   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
180   return impl.GetModelLoadResult(modelUri);
181 }
182
183 uint32_t ModelCacheManager::GetModelCacheRefCount(std::string modelUri)
184 {
185   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
186   return impl.GetModelCacheRefCount(modelUri);
187 }
188
189 Dali::ConditionalWait& ModelCacheManager::GetLoadSceneConditionalWaitInstance(std::string modelUri)
190 {
191   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
192   return impl.GetLoadSceneConditionalWaitInstance(modelUri);
193 }
194
195 Dali::ConditionalWait& ModelCacheManager::GetLoadRawResourceConditionalWaitInstance(std::string modelUri)
196 {
197   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
198   return impl.GetLoadRawResourceConditionalWaitInstance(modelUri);
199 }
200
201 void ModelCacheManager::ReferenceModelCache(std::string modelUri)
202 {
203   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
204   impl.ReferenceModelCache(modelUri);
205 }
206
207 void ModelCacheManager::UnreferenceModelCache(std::string modelUri)
208 {
209   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
210   impl.UnreferenceModelCache(modelUri);
211 }
212
213 bool ModelCacheManager::IsSceneLoaded(std::string modelUri)
214 {
215   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
216   return impl.IsSceneLoaded(modelUri);
217 }
218
219 void ModelCacheManager::SetSceneLoaded(std::string modelUri, bool isSceneLoaded)
220 {
221   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
222   impl.SetSceneLoaded(modelUri, isSceneLoaded);
223 }
224
225 bool ModelCacheManager::IsSceneLoading(std::string modelUri)
226 {
227   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
228   return impl.IsSceneLoading(modelUri);
229 }
230
231 void ModelCacheManager::SetSceneLoading(std::string modelUri, bool isSceneLoading)
232 {
233   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
234   impl.SetSceneLoading(modelUri, isSceneLoading);
235 }
236
237 } // namespace Dali::Scene3D::Internal