2 * Copyright (c) 2024 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-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>
31 using namespace Toolkit;
39 const char* const RESOURCE_TYPE_NAMES[] = {
48 const char* GetResourceTypeName(ResourceType::Value type)
50 return RESOURCE_TYPE_NAMES[static_cast<int>(type)];
53 ResourceBundle::ResourceBundle()
54 : mRawResourcesLoading(false),
55 mResourcesGenerating(false),
56 mRawResourcesLoaded(false),
57 mResourcesGenerated(false){};
59 ResourceRefCounts ResourceBundle::CreateRefCounter() const
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);
69 void ResourceBundle::CountEnvironmentReferences()
71 auto& environmentRefCounts = mReferenceCounts[ResourceType::Environment];
73 const auto& materialRefs = mReferenceCounts[ResourceType::Material];
74 for(uint32_t i = 0, iEnd = materialRefs.Size(); i != iEnd; ++i)
76 if(materialRefs[i] > 0)
78 ++environmentRefCounts[mMaterials[i].first.mEnvironmentIdx];
83 void ResourceBundle::LoadResources(PathProvider pathProvider, Options::Type options)
85 mRawResourcesLoading = true;
86 mResourcesGenerating = true;
88 const auto kForceLoad = MaskMatch(options, Options::ForceReload);
89 const auto kKeepUnused = MaskMatch(options, Options::KeepUnused);
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)
95 auto refCount = refCountEnvMaps[i];
96 auto& iEnvMap = mEnvironmentMaps[i];
97 if(refCount > 0 && (kForceLoad || !iEnvMap.second.IsLoaded()))
99 auto raw = iEnvMap.first.LoadRaw(environmentsPath);
100 iEnvMap.second = iEnvMap.first.Load(std::move(raw));
102 else if(!kKeepUnused && refCount == 0 && iEnvMap.second.IsLoaded())
104 iEnvMap.second.mDiffuse = Texture();
105 iEnvMap.second.mSpecular = Texture();
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)
113 auto refCount = refCountShaders[i];
114 auto& iShader = mShaders[i];
115 if(refCount > 0 && (kForceLoad || !iShader.second))
117 auto raw = iShader.first.LoadRaw(shadersPath);
118 iShader.second = iShader.first.Load(std::move(raw));
120 else if(!kKeepUnused && refCount == 0 && iShader.second)
122 iShader.second = Shader();
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)
130 auto refCount = refCountMeshes[i];
131 auto& iMesh = mMeshes[i];
132 if(refCount > 0 && (kForceLoad || !iMesh.second.geometry))
134 auto raw = iMesh.first.LoadRaw(modelsPath, mBuffers);
135 iMesh.second = iMesh.first.Load(std::move(raw));
137 else if(!kKeepUnused && refCount == 0 && iMesh.second.geometry)
139 iMesh.second.geometry = Geometry();
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)
147 auto refCount = refCountMaterials[i];
148 auto& iMaterial = mMaterials[i];
149 if(refCount > 0 && (kForceLoad || !iMaterial.second))
151 auto raw = iMaterial.first.LoadRaw(imagesPath);
152 iMaterial.second = iMaterial.first.Load(mEnvironmentMaps, std::move(raw));
154 else if(!kKeepUnused && refCount == 0 && iMaterial.second)
156 iMaterial.second = TextureSet();
160 mRawResourcesLoading = false;
161 mResourcesGenerating = false;
163 mRawResourcesLoaded = true;
164 mResourcesGenerated = true;
167 void ResourceBundle::LoadRawResources(PathProvider pathProvider, Options::Type options)
169 const auto kForceLoad = MaskMatch(options, Options::ForceReload);
171 if(kForceLoad || (!mRawResourcesLoaded && !mRawResourcesLoading))
173 mRawResourcesLoading = true;
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)
179 auto refCount = refCountEnvMaps[i];
180 auto& iEnvMap = mEnvironmentMaps[i];
181 if(refCount > 0 && (kForceLoad || (!iEnvMap.first.mRawData && !iEnvMap.second.IsLoaded())))
183 iEnvMap.first.mRawData = std::make_shared<EnvironmentDefinition::RawData>(iEnvMap.first.LoadRaw(environmentsPath));
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)
191 auto refCount = refCountShaders[i];
192 auto& iShader = mShaders[i];
193 if(refCount > 0 && (kForceLoad || !iShader.second))
195 iShader.first.mRawData = std::make_shared<ShaderDefinition::RawData>(iShader.first.LoadRaw(shadersPath));
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)
203 auto refCount = refCountMeshes[i];
204 auto& iMesh = mMeshes[i];
205 if(refCount > 0 && (kForceLoad || (!iMesh.first.mRawData && !iMesh.second.geometry)))
207 iMesh.first.mRawData = std::make_shared<MeshDefinition::RawData>(iMesh.first.LoadRaw(modelsPath, mBuffers));
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)
215 auto refCount = refCountMaterials[i];
216 auto& iMaterial = mMaterials[i];
217 if(refCount > 0 && (kForceLoad || (!iMaterial.first.mRawData && !iMaterial.second)))
219 iMaterial.first.mRawData = std::make_shared<MaterialDefinition::RawData>(iMaterial.first.LoadRaw(imagesPath));
223 mRawResourcesLoading = false;
224 mRawResourcesLoaded = true;
228 void ResourceBundle::GenerateResources(Options::Type options)
230 const auto kForceLoad = MaskMatch(options, Options::ForceReload);
232 if(mRawResourcesLoaded)
234 if(kForceLoad || (!mResourcesGenerated && !mResourcesGenerating))
236 mResourcesGenerating = true;
238 const auto& refCountEnvMaps = mReferenceCounts[ResourceType::Environment];
239 for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
241 auto refCount = refCountEnvMaps[i];
242 auto& iEnvMap = mEnvironmentMaps[i];
243 if(refCount > 0 && (kForceLoad || !iEnvMap.second.IsLoaded()))
245 if(iEnvMap.first.mRawData)
247 iEnvMap.second = iEnvMap.first.Load(std::move(*(iEnvMap.first.mRawData)));
251 iEnvMap.second.mDiffuse = Texture();
252 iEnvMap.second.mSpecular = Texture();
257 const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
258 for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
260 auto refCount = refCountShaders[i];
261 auto& iShader = mShaders[i];
262 if(refCount > 0 && (kForceLoad || !iShader.second))
264 if(iShader.first.mRawData)
266 iShader.second = iShader.first.Load(std::move(*(iShader.first.mRawData)));
270 iShader.second = Shader();
275 const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh];
276 for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
278 auto refCount = refCountMeshes[i];
279 auto& iMesh = mMeshes[i];
280 if(refCount > 0 && (kForceLoad || !iMesh.second.geometry))
282 if(iMesh.first.mRawData)
284 iMesh.second = iMesh.first.Load(std::move(*(iMesh.first.mRawData)));
288 iMesh.second.geometry = Geometry();
293 const auto& refCountMaterials = mReferenceCounts[ResourceType::Material];
294 for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
296 auto refCount = refCountMaterials[i];
297 auto& iMaterial = mMaterials[i];
298 if(refCount > 0 && (kForceLoad || !iMaterial.second))
300 if(iMaterial.first.mRawData)
302 iMaterial.second = iMaterial.first.Load(mEnvironmentMaps, std::move(*(iMaterial.first.mRawData)));
306 iMaterial.second = TextureSet();
311 mResourcesGenerating = false;
312 mResourcesGenerated = true;
314 else if(mResourcesGenerated && !mResourcesGenerating)
316 mResourcesGenerating = true;
318 const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
319 for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
321 auto refCount = refCountShaders[i];
322 auto& iShader = mShaders[i];
324 // Always regenerating the Shader objects as they can't be shared between multiple models.
325 if(refCount > 0 || kForceLoad)
327 if(iShader.first.mRawData)
329 iShader.second = iShader.first.Load(std::move(*(iShader.first.mRawData)));
333 iShader.second = Shader();
338 mResourcesGenerating = false;
343 } // namespace Loader
344 } // namespace Scene3D