DALi Version 2.2.11
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / loader / resource-bundle.cpp
1 /*
2  * Copyright (c) 2022 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
22 #include <cstring>
23 #include <fstream>
24 #include <istream>
25 #include "dali-toolkit/public-api/image-loader/sync-image-loader.h"
26 #include "dali/public-api/rendering/sampler.h"
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 ResourceRefCounts ResourceBundle::CreateRefCounter() const
53 {
54   ResourceRefCounts refCounts(4);
55   refCounts[ResourceType::Environment].Resize(mEnvironmentMaps.size(), 0u);
56   refCounts[ResourceType::Shader].Resize(mShaders.size(), 0u);
57   refCounts[ResourceType::Mesh].Resize(mMeshes.size(), 0u);
58   refCounts[ResourceType::Material].Resize(mMaterials.size(), 0u);
59   return refCounts;
60 }
61
62 void ResourceBundle::CountEnvironmentReferences(ResourceRefCounts& refCounts) const
63 {
64   auto& environmentRefCounts = refCounts[ResourceType::Environment];
65
66   const auto& materialRefs = refCounts[ResourceType::Material];
67   for(uint32_t i = 0, iEnd = materialRefs.Size(); i != iEnd; ++i)
68   {
69     if(materialRefs[i] > 0)
70     {
71       ++environmentRefCounts[mMaterials[i].first.mEnvironmentIdx];
72     }
73   }
74 }
75
76 void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvider pathProvider, Options::Type options)
77 {
78   const auto kForceLoad  = MaskMatch(options, Options::ForceReload);
79   const auto kKeepUnused = MaskMatch(options, Options::KeepUnused);
80
81   const auto& refCountEnvMaps  = refCounts[ResourceType::Environment];
82   auto        environmentsPath = pathProvider(ResourceType::Environment);
83   for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
84   {
85     auto  refCount = refCountEnvMaps[i];
86     auto& iEnvMap  = mEnvironmentMaps[i];
87     if(refCount > 0 && (kForceLoad || !iEnvMap.second.IsLoaded()))
88     {
89       auto raw       = iEnvMap.first.LoadRaw(environmentsPath);
90       iEnvMap.second = iEnvMap.first.Load(std::move(raw));
91     }
92     else if(!kKeepUnused && refCount == 0 && iEnvMap.second.IsLoaded())
93     {
94       iEnvMap.second.mDiffuse  = Texture();
95       iEnvMap.second.mSpecular = Texture();
96     }
97   }
98
99   const auto& refCountShaders = refCounts[ResourceType::Shader];
100   auto        shadersPath     = pathProvider(ResourceType::Shader);
101   for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
102   {
103     auto  refCount = refCountShaders[i];
104     auto& iShader  = mShaders[i];
105     if(refCount > 0 && (kForceLoad || !iShader.second))
106     {
107       auto raw       = iShader.first.LoadRaw(shadersPath);
108       iShader.second = iShader.first.Load(std::move(raw));
109     }
110     else if(!kKeepUnused && refCount == 0 && iShader.second)
111     {
112       iShader.second = Shader();
113     }
114   }
115
116   const auto& refCountMeshes = refCounts[ResourceType::Mesh];
117   auto        modelsPath     = pathProvider(ResourceType::Mesh);
118   for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
119   {
120     auto  refCount = refCountMeshes[i];
121     auto& iMesh    = mMeshes[i];
122     if(refCount > 0 && (kForceLoad || !iMesh.second.geometry))
123     {
124       auto raw     = iMesh.first.LoadRaw(modelsPath);
125       iMesh.second = iMesh.first.Load(std::move(raw));
126     }
127     else if(!kKeepUnused && refCount == 0 && iMesh.second.geometry)
128     {
129       iMesh.second.geometry = Geometry();
130     }
131   }
132
133   const auto& refCountMaterials = refCounts[ResourceType::Material];
134   auto        imagesPath        = pathProvider(ResourceType::Material);
135   for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
136   {
137     auto  refCount  = refCountMaterials[i];
138     auto& iMaterial = mMaterials[i];
139     if(refCount > 0 && (kForceLoad || !iMaterial.second))
140     {
141       auto raw         = iMaterial.first.LoadRaw(imagesPath);
142       iMaterial.second = iMaterial.first.Load(mEnvironmentMaps, std::move(raw));
143     }
144     else if(!kKeepUnused && refCount == 0 && iMaterial.second)
145     {
146       iMaterial.second = TextureSet();
147     }
148   }
149 }
150
151 void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathProvider pathProvider, Options::Type options)
152 {
153   const auto kForceLoad  = MaskMatch(options, Options::ForceReload);
154
155   const auto& refCountEnvMaps  = refCounts[ResourceType::Environment];
156   auto        environmentsPath = pathProvider(ResourceType::Environment);
157   for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
158   {
159     auto  refCount = refCountEnvMaps[i];
160     auto& iEnvMap  = mEnvironmentMaps[i];
161     if(refCount > 0 && (kForceLoad || !iEnvMap.second.IsLoaded()))
162     {
163       iEnvMap.first.mRawData = std::make_shared<EnvironmentDefinition::RawData>(iEnvMap.first.LoadRaw(environmentsPath));
164     }
165   }
166
167   const auto& refCountShaders = refCounts[ResourceType::Shader];
168   auto        shadersPath     = pathProvider(ResourceType::Shader);
169   for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
170   {
171     auto  refCount = refCountShaders[i];
172     auto& iShader  = mShaders[i];
173     if(refCount > 0 && (kForceLoad || !iShader.second))
174     {
175       iShader.first.mRawData = std::make_shared<ShaderDefinition::RawData>(iShader.first.LoadRaw(shadersPath));
176     }
177   }
178
179   const auto& refCountMeshes = refCounts[ResourceType::Mesh];
180   auto        modelsPath     = pathProvider(ResourceType::Mesh);
181   for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
182   {
183     auto  refCount = refCountMeshes[i];
184     auto& iMesh    = mMeshes[i];
185     if(refCount > 0 && (kForceLoad || !iMesh.second.geometry))
186     {
187       iMesh.first.mRawData = std::make_shared<MeshDefinition::RawData>(iMesh.first.LoadRaw(modelsPath));
188     }
189   }
190
191   const auto& refCountMaterials = refCounts[ResourceType::Material];
192   auto        imagesPath        = pathProvider(ResourceType::Material);
193   for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
194   {
195     auto  refCount  = refCountMaterials[i];
196     auto& iMaterial = mMaterials[i];
197     if(refCount > 0 && (kForceLoad || !iMaterial.second))
198     {
199       iMaterial.first.mRawData = std::make_shared<MaterialDefinition::RawData>(iMaterial.first.LoadRaw(imagesPath));
200     }
201   }
202 }
203
204 void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Options::Type options)
205 {
206   const auto& refCountEnvMaps = refCounts[ResourceType::Environment];
207   for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
208   {
209     auto& iEnvMap = mEnvironmentMaps[i];
210     if(iEnvMap.first.mRawData)
211     {
212       iEnvMap.second = iEnvMap.first.Load(std::move(*(iEnvMap.first.mRawData)));
213     }
214     else
215     {
216       iEnvMap.second.mDiffuse  = Texture();
217       iEnvMap.second.mSpecular = Texture();
218     }
219   }
220
221   const auto& refCountShaders = refCounts[ResourceType::Shader];
222   for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
223   {
224     auto& iShader = mShaders[i];
225     if(iShader.first.mRawData)
226     {
227       iShader.second = iShader.first.Load(std::move(*(iShader.first.mRawData)));
228     }
229     else
230     {
231       iShader.second = Shader();
232     }
233   }
234
235   const auto& refCountMeshes = refCounts[ResourceType::Mesh];
236   for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
237   {
238     auto& iMesh = mMeshes[i];
239     if(iMesh.first.mRawData)
240     {
241       iMesh.second = iMesh.first.Load(std::move(*(iMesh.first.mRawData)));
242     }
243     else
244     {
245       iMesh.second.geometry = Geometry();
246     }
247   }
248
249   const auto& refCountMaterials = refCounts[ResourceType::Material];
250   for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
251   {
252     auto& iMaterial = mMaterials[i];
253     if(iMaterial.first.mRawData)
254     {
255       iMaterial.second = iMaterial.first.Load(mEnvironmentMaps, std::move(*(iMaterial.first.mRawData)));
256     }
257     else
258     {
259       iMaterial.second = TextureSet();
260     }
261   }
262 }
263
264 } // namespace Loader
265 } // namespace Scene3D
266 } // namespace Dali