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)
60 ResourceRefCounts ResourceBundle::CreateRefCounter() const
62 ResourceRefCounts refCounts(4);
63 refCounts[ResourceType::Environment].Resize(mEnvironmentMaps.size(), 0u);
64 refCounts[ResourceType::Shader].Resize(mShaders.size(), 0u);
65 refCounts[ResourceType::Mesh].Resize(mMeshes.size(), 0u);
66 refCounts[ResourceType::Material].Resize(mMaterials.size(), 0u);
70 void ResourceBundle::CountEnvironmentReferences()
72 auto& environmentRefCounts = mReferenceCounts[ResourceType::Environment];
74 const auto& materialRefs = mReferenceCounts[ResourceType::Material];
75 for(uint32_t i = 0, iEnd = materialRefs.Size(); i != iEnd; ++i)
77 if(materialRefs[i] > 0)
79 ++environmentRefCounts[mMaterials[i].first.mEnvironmentIdx];
84 void ResourceBundle::LoadResources(PathProvider pathProvider, Options::Type options)
86 mRawResourcesLoading = true;
87 mResourcesGenerating = true;
89 const auto kForceLoad = MaskMatch(options, Options::ForceReload);
90 const auto kKeepUnused = MaskMatch(options, Options::KeepUnused);
92 const auto& refCountEnvMaps = mReferenceCounts[ResourceType::Environment];
93 auto environmentsPath = pathProvider(ResourceType::Environment);
94 for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
96 auto refCount = refCountEnvMaps[i];
97 auto& iEnvMap = mEnvironmentMaps[i];
98 if(refCount > 0 && (kForceLoad || !iEnvMap.second.IsLoaded()))
100 auto raw = iEnvMap.first.LoadRaw(environmentsPath);
101 iEnvMap.second = iEnvMap.first.Load(std::move(raw));
103 else if(!kKeepUnused && refCount == 0 && iEnvMap.second.IsLoaded())
105 iEnvMap.second.mDiffuse = Texture();
106 iEnvMap.second.mSpecular = Texture();
110 const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
111 auto shadersPath = pathProvider(ResourceType::Shader);
112 for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
114 auto refCount = refCountShaders[i];
115 auto& iShader = mShaders[i];
116 if(refCount > 0 && (kForceLoad || !iShader.second))
118 auto raw = iShader.first.LoadRaw(shadersPath);
119 iShader.second = iShader.first.Load(std::move(raw));
121 else if(!kKeepUnused && refCount == 0 && iShader.second)
123 iShader.second = Shader();
127 const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh];
128 auto modelsPath = pathProvider(ResourceType::Mesh);
129 for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
131 auto refCount = refCountMeshes[i];
132 auto& iMesh = mMeshes[i];
133 if(refCount > 0 && (kForceLoad || !iMesh.second.geometry))
135 auto raw = iMesh.first.LoadRaw(modelsPath, mBuffers);
136 iMesh.second = iMesh.first.Load(std::move(raw));
138 else if(!kKeepUnused && refCount == 0 && iMesh.second.geometry)
140 iMesh.second.geometry = Geometry();
144 const auto& refCountMaterials = mReferenceCounts[ResourceType::Material];
145 auto imagesPath = pathProvider(ResourceType::Material);
146 for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
148 auto refCount = refCountMaterials[i];
149 auto& iMaterial = mMaterials[i];
150 if(refCount > 0 && (kForceLoad || !iMaterial.second))
152 auto raw = iMaterial.first.LoadRaw(imagesPath);
153 iMaterial.second = iMaterial.first.Load(mEnvironmentMaps, std::move(raw));
155 else if(!kKeepUnused && refCount == 0 && iMaterial.second)
157 iMaterial.second = TextureSet();
161 mRawResourcesLoading = false;
162 mResourcesGenerating = false;
164 mRawResourcesLoaded = true;
165 mResourcesGenerated = true;
168 void ResourceBundle::LoadRawResources(PathProvider pathProvider, Options::Type options)
170 const auto kForceLoad = MaskMatch(options, Options::ForceReload);
172 if(kForceLoad || (!mRawResourcesLoaded && !mRawResourcesLoading))
174 mRawResourcesLoading = true;
176 const auto& refCountEnvMaps = mReferenceCounts[ResourceType::Environment];
177 auto environmentsPath = pathProvider(ResourceType::Environment);
178 for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
180 auto refCount = refCountEnvMaps[i];
181 auto& iEnvMap = mEnvironmentMaps[i];
182 if(refCount > 0 && (kForceLoad || (!iEnvMap.first.mRawData && !iEnvMap.second.IsLoaded())))
184 iEnvMap.first.mRawData = std::make_shared<EnvironmentDefinition::RawData>(iEnvMap.first.LoadRaw(environmentsPath));
188 const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
189 auto shadersPath = pathProvider(ResourceType::Shader);
190 for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
192 auto refCount = refCountShaders[i];
193 auto& iShader = mShaders[i];
194 if(refCount > 0 && (kForceLoad || !iShader.second))
196 iShader.first.mRawData = std::make_shared<ShaderDefinition::RawData>(iShader.first.LoadRaw(shadersPath));
200 const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh];
201 auto modelsPath = pathProvider(ResourceType::Mesh);
202 for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
204 auto refCount = refCountMeshes[i];
205 auto& iMesh = mMeshes[i];
206 if(refCount > 0 && (kForceLoad || (!iMesh.first.mRawData && !iMesh.second.geometry)))
208 iMesh.first.mRawData = std::make_shared<MeshDefinition::RawData>(iMesh.first.LoadRaw(modelsPath, mBuffers));
212 const auto& refCountMaterials = mReferenceCounts[ResourceType::Material];
213 auto imagesPath = pathProvider(ResourceType::Material);
214 for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
216 auto refCount = refCountMaterials[i];
217 auto& iMaterial = mMaterials[i];
218 if(refCount > 0 && (kForceLoad || (!iMaterial.first.mRawData && !iMaterial.second)))
220 iMaterial.first.mRawData = std::make_shared<MaterialDefinition::RawData>(iMaterial.first.LoadRaw(imagesPath));
224 mRawResourcesLoading = false;
225 mRawResourcesLoaded = true;
229 void ResourceBundle::GenerateResources(Options::Type options)
231 const auto kForceLoad = MaskMatch(options, Options::ForceReload);
233 if(mRawResourcesLoaded)
235 if(kForceLoad || (!mResourcesGenerated && !mResourcesGenerating))
237 mResourcesGenerating = true;
239 const auto& refCountEnvMaps = mReferenceCounts[ResourceType::Environment];
240 for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
242 auto refCount = refCountEnvMaps[i];
243 auto& iEnvMap = mEnvironmentMaps[i];
244 if(refCount > 0 && (kForceLoad || !iEnvMap.second.IsLoaded()))
246 if(iEnvMap.first.mRawData)
248 iEnvMap.second = iEnvMap.first.Load(std::move(*(iEnvMap.first.mRawData)));
252 iEnvMap.second.mDiffuse = Texture();
253 iEnvMap.second.mSpecular = Texture();
258 const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
259 for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
261 auto refCount = refCountShaders[i];
262 auto& iShader = mShaders[i];
263 if(refCount > 0 && (kForceLoad || !iShader.second))
265 if(iShader.first.mRawData)
267 iShader.second = iShader.first.Load(std::move(*(iShader.first.mRawData)));
271 iShader.second = Shader();
276 const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh];
277 for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
279 auto refCount = refCountMeshes[i];
280 auto& iMesh = mMeshes[i];
281 if(refCount > 0 && (kForceLoad || !iMesh.second.geometry))
283 if(iMesh.first.mRawData)
285 iMesh.second = iMesh.first.Load(std::move(*(iMesh.first.mRawData)));
289 iMesh.second.geometry = Geometry();
294 const auto& refCountMaterials = mReferenceCounts[ResourceType::Material];
295 for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
297 auto refCount = refCountMaterials[i];
298 auto& iMaterial = mMaterials[i];
299 if(refCount > 0 && (kForceLoad || !iMaterial.second))
301 if(iMaterial.first.mRawData)
303 iMaterial.second = iMaterial.first.Load(mEnvironmentMaps, std::move(*(iMaterial.first.mRawData)));
307 iMaterial.second = TextureSet();
312 mResourcesGenerating = false;
313 mResourcesGenerated = true;
315 else if(mResourcesGenerated && !mResourcesGenerating)
317 mResourcesGenerating = true;
319 const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
320 for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
322 auto refCount = refCountShaders[i];
323 auto& iShader = mShaders[i];
325 // Always regenerating the Shader objects as they can't be shared between multiple models.
326 if(refCount > 0 || kForceLoad)
328 if(iShader.first.mRawData)
330 iShader.second = iShader.first.Load(std::move(*(iShader.first.mRawData)));
334 iShader.second = Shader();
339 mResourcesGenerating = false;
344 } // namespace Loader
345 } // namespace Scene3D