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