6b4dde69492001e7ea361d49bbbdb530423c84fe
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / loader / resource-bundle.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 // FILE HEADER
19 #include <dali-scene3d/public-api/loader/resource-bundle.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
23 #include <dali/public-api/rendering/sampler.h>
24 #include <cstring>
25 #include <fstream>
26 #include <istream>
27
28 namespace Dali
29 {
30 using namespace Toolkit;
31
32 namespace Scene3D
33 {
34 namespace Loader
35 {
36 namespace
37 {
38 const char* const RESOURCE_TYPE_NAMES[] = {
39   "Environment",
40   "Shader",
41   "Mesh",
42   "Material",
43 };
44
45 } // namespace
46
47 const char* GetResourceTypeName(ResourceType::Value type)
48 {
49   return RESOURCE_TYPE_NAMES[static_cast<int>(type)];
50 }
51
52 ResourceBundle::ResourceBundle()
53 : mRawResourcesLoading(false),
54   mResourcesGenerating(false),
55   mRawResourcesLoaded(false),
56   mResourcesGenerated(false){};
57
58 ResourceRefCounts ResourceBundle::CreateRefCounter() const
59 {
60   ResourceRefCounts refCounts(4);
61   refCounts[ResourceType::Environment].Resize(mEnvironmentMaps.size(), 0u);
62   refCounts[ResourceType::Shader].Resize(mShaders.size(), 0u);
63   refCounts[ResourceType::Mesh].Resize(mMeshes.size(), 0u);
64   refCounts[ResourceType::Material].Resize(mMaterials.size(), 0u);
65   return refCounts;
66 }
67
68 void ResourceBundle::CountEnvironmentReferences()
69 {
70   auto& environmentRefCounts = mReferenceCounts[ResourceType::Environment];
71
72   const auto& materialRefs = mReferenceCounts[ResourceType::Material];
73   for(uint32_t i = 0, iEnd = materialRefs.Size(); i != iEnd; ++i)
74   {
75     if(materialRefs[i] > 0)
76     {
77       ++environmentRefCounts[mMaterials[i].first.mEnvironmentIdx];
78     }
79   }
80 }
81
82 void ResourceBundle::LoadResources(PathProvider pathProvider, Options::Type options)
83 {
84   mRawResourcesLoading = true;
85   mResourcesGenerating = true;
86
87   const auto kForceLoad  = MaskMatch(options, Options::ForceReload);
88   const auto kKeepUnused = MaskMatch(options, Options::KeepUnused);
89
90   const auto& refCountEnvMaps  = mReferenceCounts[ResourceType::Environment];
91   auto        environmentsPath = pathProvider(ResourceType::Environment);
92   for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
93   {
94     auto  refCount = refCountEnvMaps[i];
95     auto& iEnvMap  = mEnvironmentMaps[i];
96     if(refCount > 0 && (kForceLoad || !iEnvMap.second.IsLoaded()))
97     {
98       auto raw       = iEnvMap.first.LoadRaw(environmentsPath);
99       iEnvMap.second = iEnvMap.first.Load(std::move(raw));
100     }
101     else if(!kKeepUnused && refCount == 0 && iEnvMap.second.IsLoaded())
102     {
103       iEnvMap.second.mDiffuse  = Texture();
104       iEnvMap.second.mSpecular = Texture();
105     }
106   }
107
108   const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
109   auto        shadersPath     = pathProvider(ResourceType::Shader);
110   for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
111   {
112     auto  refCount = refCountShaders[i];
113     auto& iShader  = mShaders[i];
114     if(refCount > 0 && (kForceLoad || !iShader.second))
115     {
116       auto raw       = iShader.first.LoadRaw(shadersPath);
117       iShader.second = iShader.first.Load(std::move(raw));
118     }
119     else if(!kKeepUnused && refCount == 0 && iShader.second)
120     {
121       iShader.second = Shader();
122     }
123   }
124
125   const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh];
126   auto        modelsPath     = pathProvider(ResourceType::Mesh);
127   for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
128   {
129     auto  refCount = refCountMeshes[i];
130     auto& iMesh    = mMeshes[i];
131     if(refCount > 0 && (kForceLoad || !iMesh.second.geometry))
132     {
133       auto raw     = iMesh.first.LoadRaw(modelsPath, mBuffers);
134       iMesh.second = iMesh.first.Load(std::move(raw));
135     }
136     else if(!kKeepUnused && refCount == 0 && iMesh.second.geometry)
137     {
138       iMesh.second.geometry = Geometry();
139     }
140   }
141
142   const auto& refCountMaterials = mReferenceCounts[ResourceType::Material];
143   auto        imagesPath        = pathProvider(ResourceType::Material);
144   for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
145   {
146     auto  refCount  = refCountMaterials[i];
147     auto& iMaterial = mMaterials[i];
148     if(refCount > 0 && (kForceLoad || !iMaterial.second))
149     {
150       auto raw         = iMaterial.first.LoadRaw(imagesPath);
151       iMaterial.second = iMaterial.first.Load(mEnvironmentMaps, std::move(raw));
152     }
153     else if(!kKeepUnused && refCount == 0 && iMaterial.second)
154     {
155       iMaterial.second = TextureSet();
156     }
157   }
158
159   mRawResourcesLoading = false;
160   mResourcesGenerating = false;
161
162   mRawResourcesLoaded = true;
163   mResourcesGenerated = true;
164 }
165
166 void ResourceBundle::LoadRawResources(PathProvider pathProvider, Options::Type options)
167 {
168   const auto kForceLoad = MaskMatch(options, Options::ForceReload);
169
170   if(kForceLoad || (!mRawResourcesLoaded && !mRawResourcesLoading))
171   {
172     mRawResourcesLoading = true;
173
174     const auto& refCountEnvMaps  = mReferenceCounts[ResourceType::Environment];
175     auto        environmentsPath = pathProvider(ResourceType::Environment);
176     for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
177     {
178       auto  refCount = refCountEnvMaps[i];
179       auto& iEnvMap  = mEnvironmentMaps[i];
180       if(refCount > 0 && (kForceLoad || (!iEnvMap.first.mRawData && !iEnvMap.second.IsLoaded())))
181       {
182         iEnvMap.first.mRawData = std::make_shared<EnvironmentDefinition::RawData>(iEnvMap.first.LoadRaw(environmentsPath));
183       }
184     }
185
186     const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
187     auto        shadersPath     = pathProvider(ResourceType::Shader);
188     for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
189     {
190       auto  refCount = refCountShaders[i];
191       auto& iShader  = mShaders[i];
192       if(refCount > 0 && (kForceLoad || !iShader.second))
193       {
194         iShader.first.mRawData = std::make_shared<ShaderDefinition::RawData>(iShader.first.LoadRaw(shadersPath));
195       }
196     }
197
198     const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh];
199     auto        modelsPath     = pathProvider(ResourceType::Mesh);
200     for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
201     {
202       auto  refCount = refCountMeshes[i];
203       auto& iMesh    = mMeshes[i];
204       if(refCount > 0 && (kForceLoad || (!iMesh.first.mRawData && !iMesh.second.geometry)))
205       {
206         iMesh.first.mRawData = std::make_shared<MeshDefinition::RawData>(iMesh.first.LoadRaw(modelsPath, mBuffers));
207       }
208     }
209
210     const auto& refCountMaterials = mReferenceCounts[ResourceType::Material];
211     auto        imagesPath        = pathProvider(ResourceType::Material);
212     for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
213     {
214       auto  refCount  = refCountMaterials[i];
215       auto& iMaterial = mMaterials[i];
216       if(refCount > 0 && (kForceLoad || (!iMaterial.first.mRawData && !iMaterial.second)))
217       {
218         iMaterial.first.mRawData = std::make_shared<MaterialDefinition::RawData>(iMaterial.first.LoadRaw(imagesPath));
219       }
220     }
221
222     mRawResourcesLoading = false;
223     mRawResourcesLoaded  = true;
224   }
225 }
226
227 void ResourceBundle::GenerateResources(Options::Type options)
228 {
229   const auto kForceLoad = MaskMatch(options, Options::ForceReload);
230
231   if(mRawResourcesLoaded)
232   {
233     if(kForceLoad || (!mResourcesGenerated && !mResourcesGenerating))
234     {
235       mResourcesGenerating = true;
236
237       const auto& refCountEnvMaps = mReferenceCounts[ResourceType::Environment];
238       for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
239       {
240         auto  refCount = refCountEnvMaps[i];
241         auto& iEnvMap  = mEnvironmentMaps[i];
242         if(refCount > 0 && (kForceLoad || !iEnvMap.second.IsLoaded()))
243         {
244           if(iEnvMap.first.mRawData)
245           {
246             iEnvMap.second = iEnvMap.first.Load(std::move(*(iEnvMap.first.mRawData)));
247           }
248           else
249           {
250             iEnvMap.second.mDiffuse  = Texture();
251             iEnvMap.second.mSpecular = Texture();
252           }
253         }
254       }
255
256       const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
257       for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
258       {
259         auto  refCount = refCountShaders[i];
260         auto& iShader  = mShaders[i];
261         if(refCount > 0 && (kForceLoad || !iShader.second))
262         {
263           if(iShader.first.mRawData)
264           {
265             iShader.second = iShader.first.Load(std::move(*(iShader.first.mRawData)));
266           }
267           else
268           {
269             iShader.second = Shader();
270           }
271         }
272       }
273
274       const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh];
275       for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
276       {
277         auto  refCount = refCountMeshes[i];
278         auto& iMesh    = mMeshes[i];
279         if(refCount > 0 && (kForceLoad || !iMesh.second.geometry))
280         {
281           if(iMesh.first.mRawData)
282           {
283             iMesh.second = iMesh.first.Load(std::move(*(iMesh.first.mRawData)));
284           }
285           else
286           {
287             iMesh.second.geometry = Geometry();
288           }
289         }
290       }
291
292       const auto& refCountMaterials = mReferenceCounts[ResourceType::Material];
293       for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
294       {
295         auto  refCount  = refCountMaterials[i];
296         auto& iMaterial = mMaterials[i];
297         if(refCount > 0 && (kForceLoad || !iMaterial.second))
298         {
299           if(iMaterial.first.mRawData)
300           {
301             iMaterial.second = iMaterial.first.Load(mEnvironmentMaps, std::move(*(iMaterial.first.mRawData)));
302           }
303           else
304           {
305             iMaterial.second = TextureSet();
306           }
307         }
308       }
309
310       mResourcesGenerating = false;
311       mResourcesGenerated  = true;
312     }
313     else if(mResourcesGenerated && !mResourcesGenerating)
314     {
315       mResourcesGenerating = true;
316
317       const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
318       for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
319       {
320         auto  refCount = refCountShaders[i];
321         auto& iShader  = mShaders[i];
322
323         // Always regenerating the Shader objects as they can't be shared between multiple models.
324         if(refCount > 0 || kForceLoad)
325         {
326           if(iShader.first.mRawData)
327           {
328             iShader.second = iShader.first.Load(std::move(*(iShader.first.mRawData)));
329           }
330           else
331           {
332             iShader.second = Shader();
333           }
334         }
335       }
336
337       mResourcesGenerating = false;
338     }
339   }
340 }
341
342 } // namespace Loader
343 } // namespace Scene3D
344 } // namespace Dali