2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-scene3d/public-api/loader/resource-bundle.h>
22 #include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
23 #include <dali/public-api/rendering/sampler.h>
30 using namespace Toolkit;
38 const char* const RESOURCE_TYPE_NAMES[] = {
47 const char* GetResourceTypeName(ResourceType::Value type)
49 return RESOURCE_TYPE_NAMES[static_cast<int>(type)];
52 ResourceBundle::ResourceBundle()
53 : mRawResourcesLoading(false),
54 mResourcesGenerating(false),
55 mRawResourcesLoaded(false),
56 mResourcesGenerated(false){};
58 ResourceRefCounts ResourceBundle::CreateRefCounter() const
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);
68 void ResourceBundle::CountEnvironmentReferences()
70 auto& environmentRefCounts = mReferenceCounts[ResourceType::Environment];
72 const auto& materialRefs = mReferenceCounts[ResourceType::Material];
73 for(uint32_t i = 0, iEnd = materialRefs.Size(); i != iEnd; ++i)
75 if(materialRefs[i] > 0)
77 ++environmentRefCounts[mMaterials[i].first.mEnvironmentIdx];
82 void ResourceBundle::LoadResources(PathProvider pathProvider, Options::Type options)
84 mRawResourcesLoading = true;
85 mResourcesGenerating = true;
87 const auto kForceLoad = MaskMatch(options, Options::ForceReload);
88 const auto kKeepUnused = MaskMatch(options, Options::KeepUnused);
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)
94 auto refCount = refCountEnvMaps[i];
95 auto& iEnvMap = mEnvironmentMaps[i];
96 if(refCount > 0 && (kForceLoad || !iEnvMap.second.IsLoaded()))
98 auto raw = iEnvMap.first.LoadRaw(environmentsPath);
99 iEnvMap.second = iEnvMap.first.Load(std::move(raw));
101 else if(!kKeepUnused && refCount == 0 && iEnvMap.second.IsLoaded())
103 iEnvMap.second.mDiffuse = Texture();
104 iEnvMap.second.mSpecular = Texture();
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)
112 auto refCount = refCountShaders[i];
113 auto& iShader = mShaders[i];
114 if(refCount > 0 && (kForceLoad || !iShader.second))
116 auto raw = iShader.first.LoadRaw(shadersPath);
117 iShader.second = iShader.first.Load(std::move(raw));
119 else if(!kKeepUnused && refCount == 0 && iShader.second)
121 iShader.second = Shader();
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)
129 auto refCount = refCountMeshes[i];
130 auto& iMesh = mMeshes[i];
131 if(refCount > 0 && (kForceLoad || !iMesh.second.geometry))
133 auto raw = iMesh.first.LoadRaw(modelsPath, mBuffers);
134 iMesh.second = iMesh.first.Load(std::move(raw));
136 else if(!kKeepUnused && refCount == 0 && iMesh.second.geometry)
138 iMesh.second.geometry = Geometry();
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)
146 auto refCount = refCountMaterials[i];
147 auto& iMaterial = mMaterials[i];
148 if(refCount > 0 && (kForceLoad || !iMaterial.second))
150 auto raw = iMaterial.first.LoadRaw(imagesPath);
151 iMaterial.second = iMaterial.first.Load(mEnvironmentMaps, std::move(raw));
153 else if(!kKeepUnused && refCount == 0 && iMaterial.second)
155 iMaterial.second = TextureSet();
159 mRawResourcesLoading = false;
160 mResourcesGenerating = false;
162 mRawResourcesLoaded = true;
163 mResourcesGenerated = true;
166 void ResourceBundle::LoadRawResources(PathProvider pathProvider, Options::Type options)
168 const auto kForceLoad = MaskMatch(options, Options::ForceReload);
170 if(kForceLoad || (!mRawResourcesLoaded && !mRawResourcesLoading))
172 mRawResourcesLoading = true;
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)
178 auto refCount = refCountEnvMaps[i];
179 auto& iEnvMap = mEnvironmentMaps[i];
180 if(refCount > 0 && (kForceLoad || (!iEnvMap.first.mRawData && !iEnvMap.second.IsLoaded())))
182 iEnvMap.first.mRawData = std::make_shared<EnvironmentDefinition::RawData>(iEnvMap.first.LoadRaw(environmentsPath));
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)
190 auto refCount = refCountShaders[i];
191 auto& iShader = mShaders[i];
192 if(refCount > 0 && (kForceLoad || !iShader.second))
194 iShader.first.mRawData = std::make_shared<ShaderDefinition::RawData>(iShader.first.LoadRaw(shadersPath));
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)
202 auto refCount = refCountMeshes[i];
203 auto& iMesh = mMeshes[i];
204 if(refCount > 0 && (kForceLoad || (!iMesh.first.mRawData && !iMesh.second.geometry)))
206 iMesh.first.mRawData = std::make_shared<MeshDefinition::RawData>(iMesh.first.LoadRaw(modelsPath, mBuffers));
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)
214 auto refCount = refCountMaterials[i];
215 auto& iMaterial = mMaterials[i];
216 if(refCount > 0 && (kForceLoad || (!iMaterial.first.mRawData && !iMaterial.second)))
218 iMaterial.first.mRawData = std::make_shared<MaterialDefinition::RawData>(iMaterial.first.LoadRaw(imagesPath));
222 mRawResourcesLoading = false;
223 mRawResourcesLoaded = true;
227 void ResourceBundle::GenerateResources(Options::Type options)
229 const auto kForceLoad = MaskMatch(options, Options::ForceReload);
231 if(mRawResourcesLoaded)
233 if(kForceLoad || (!mResourcesGenerated && !mResourcesGenerating))
235 mResourcesGenerating = true;
237 const auto& refCountEnvMaps = mReferenceCounts[ResourceType::Environment];
238 for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
240 auto refCount = refCountEnvMaps[i];
241 auto& iEnvMap = mEnvironmentMaps[i];
242 if(refCount > 0 && (kForceLoad || !iEnvMap.second.IsLoaded()))
244 if(iEnvMap.first.mRawData)
246 iEnvMap.second = iEnvMap.first.Load(std::move(*(iEnvMap.first.mRawData)));
250 iEnvMap.second.mDiffuse = Texture();
251 iEnvMap.second.mSpecular = Texture();
256 const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
257 for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
259 auto refCount = refCountShaders[i];
260 auto& iShader = mShaders[i];
261 if(refCount > 0 && (kForceLoad || !iShader.second))
263 if(iShader.first.mRawData)
265 iShader.second = iShader.first.Load(std::move(*(iShader.first.mRawData)));
269 iShader.second = Shader();
274 const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh];
275 for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
277 auto refCount = refCountMeshes[i];
278 auto& iMesh = mMeshes[i];
279 if(refCount > 0 && (kForceLoad || !iMesh.second.geometry))
281 if(iMesh.first.mRawData)
283 iMesh.second = iMesh.first.Load(std::move(*(iMesh.first.mRawData)));
287 iMesh.second.geometry = Geometry();
292 const auto& refCountMaterials = mReferenceCounts[ResourceType::Material];
293 for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
295 auto refCount = refCountMaterials[i];
296 auto& iMaterial = mMaterials[i];
297 if(refCount > 0 && (kForceLoad || !iMaterial.second))
299 if(iMaterial.first.mRawData)
301 iMaterial.second = iMaterial.first.Load(mEnvironmentMaps, std::move(*(iMaterial.first.mRawData)));
305 iMaterial.second = TextureSet();
310 mResourcesGenerating = false;
311 mResourcesGenerated = true;
313 else if(mResourcesGenerated && !mResourcesGenerating)
315 mResourcesGenerating = true;
317 const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
318 for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
320 auto refCount = refCountShaders[i];
321 auto& iShader = mShaders[i];
323 // Always regenerating the Shader objects as they can't be shared between multiple models.
324 if(refCount > 0 || kForceLoad)
326 if(iShader.first.mRawData)
328 iShader.second = iShader.first.Load(std::move(*(iShader.first.mRawData)));
332 iShader.second = Shader();
337 mResourcesGenerating = false;
342 } // namespace Loader
343 } // namespace Scene3D