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.
18 // Enable debug log for test coverage
19 #define DEBUG_ENABLED 1
21 #include <dali-scene3d/internal/common/image-resource-loader.h>
22 #include <dali-scene3d/internal/common/model-cache-manager.h>
23 #include <dali-scene3d/public-api/controls/model/model.h>
24 #include <dali-scene3d/public-api/loader/resource-bundle.h>
25 #include <dali-scene3d/public-api/loader/scene-definition.h>
26 #include <dali-toolkit-test-suite-utils.h>
27 #include <toolkit-event-thread-callback.h>
28 #include <toolkit-timer.h>
32 using namespace Dali::Toolkit;
33 using namespace Dali::Scene3D::Internal;
38 * For the AnimatedCube.gltf and its Assets
39 * Donated by Norbert Nopper for glTF testing.
40 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/AnimatedCube
42 const char* TEST_GLTF_FILE_NAME = TEST_RESOURCE_DIR "/AnimatedCube.gltf";
44 static bool gResourceReadyCalled = false;
46 void OnResourceReady(Control control)
48 gResourceReadyCalled = true;
52 int UtcDaliModelCacheManagerLoadModel(void)
54 ToolkitTestApplication application;
56 ModelCacheManager cacheManager = ModelCacheManager::Get();
57 DALI_TEST_EQUALS(cacheManager.GetModelCacheRefCount(TEST_GLTF_FILE_NAME), 0u, TEST_LOCATION);
59 // Load the first instance of the same model and add it to the scene
60 Scene3D::Model model1 = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
61 application.GetScene().Add(model1);
63 gResourceReadyCalled = false;
64 model1.ResourceReadySignal().Connect(&OnResourceReady);
65 DALI_TEST_EQUALS(gResourceReadyCalled, false, TEST_LOCATION);
67 application.SendNotification();
70 DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
71 application.SendNotification();
74 // Check that the loading has finished for mode1
75 DALI_TEST_EQUALS(gResourceReadyCalled, true, TEST_LOCATION);
77 // Store the value of expect ref count with one model. Detail value could be changed with detail logic of cache.
78 uint32_t refCountWithOneModel = cacheManager.GetModelCacheRefCount(TEST_GLTF_FILE_NAME);
80 // Check whether model reference is greate or equal with 1.
81 DALI_TEST_GREATER(refCountWithOneModel, 0u, TEST_LOCATION);
82 DALI_TEST_EQUALS(cacheManager.IsSceneLoading(TEST_GLTF_FILE_NAME), false, TEST_LOCATION);
83 DALI_TEST_EQUALS(cacheManager.IsSceneLoaded(TEST_GLTF_FILE_NAME), true, TEST_LOCATION);
85 // Load the second instance of the same model and add it to the scene
86 Scene3D::Model model2 = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
87 application.GetScene().Add(model2);
89 gResourceReadyCalled = false;
90 model2.ResourceReadySignal().Connect(&OnResourceReady);
91 DALI_TEST_EQUALS(gResourceReadyCalled, false, TEST_LOCATION);
93 application.SendNotification();
96 DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
97 application.SendNotification();
100 // Check that the loading has finished for model2
101 DALI_TEST_EQUALS(gResourceReadyCalled, true, TEST_LOCATION);
103 // Store the value of expect ref count with two models. Detail value could be changed with detail logic of cache.
104 uint32_t refCountWithTwoModels = cacheManager.GetModelCacheRefCount(TEST_GLTF_FILE_NAME);
106 // Check whether model reference is greate or equal with reference with one model.
107 DALI_TEST_GREATER(refCountWithTwoModels, refCountWithOneModel, TEST_LOCATION);
108 DALI_TEST_EQUALS(cacheManager.IsSceneLoading(TEST_GLTF_FILE_NAME), false, TEST_LOCATION);
109 DALI_TEST_EQUALS(cacheManager.IsSceneLoaded(TEST_GLTF_FILE_NAME), true, TEST_LOCATION);
111 Actor meshActor1 = model1.FindChildByName("AnimatedCube");
112 Actor meshActor2 = model2.FindChildByName("AnimatedCube");
113 DALI_TEST_CHECK(meshActor1);
114 DALI_TEST_CHECK(meshActor2);
116 Renderer renderer1 = meshActor1.GetRendererAt(0u);
117 Renderer renderer2 = meshActor2.GetRendererAt(0u);
118 DALI_TEST_CHECK(renderer1);
119 DALI_TEST_CHECK(renderer2);
121 // Check that the two instances use the shared textures and geometries from the cache
122 DALI_TEST_EQUALS(renderer1.GetTextures(), renderer2.GetTextures(), TEST_LOCATION);
123 DALI_TEST_EQUALS(renderer1.GetGeometry(), renderer2.GetGeometry(), TEST_LOCATION);
129 application.SendNotification();
130 application.Render();
132 // Check that the reference count of the cmodel cache is decreased after model1 is destroyed
133 DALI_TEST_EQUALS(cacheManager.GetModelCacheRefCount(TEST_GLTF_FILE_NAME), refCountWithOneModel, TEST_LOCATION);
135 // Load another instance of the same model and add it to the scene
136 Scene3D::Model model3 = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
137 application.GetScene().Add(model3);
139 gResourceReadyCalled = false;
140 model3.ResourceReadySignal().Connect(&OnResourceReady);
141 DALI_TEST_EQUALS(gResourceReadyCalled, false, TEST_LOCATION);
143 application.SendNotification();
144 application.Render();
146 DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
147 application.SendNotification();
148 application.Render();
150 // Check that the loading has finished for model3
151 DALI_TEST_EQUALS(gResourceReadyCalled, true, TEST_LOCATION);
153 // Check the value of expect ref count with two models.
154 DALI_TEST_EQUALS(cacheManager.GetModelCacheRefCount(TEST_GLTF_FILE_NAME), refCountWithTwoModels, TEST_LOCATION);
155 DALI_TEST_EQUALS(cacheManager.IsSceneLoading(TEST_GLTF_FILE_NAME), false, TEST_LOCATION);
156 DALI_TEST_EQUALS(cacheManager.IsSceneLoaded(TEST_GLTF_FILE_NAME), true, TEST_LOCATION);
158 Actor meshActor3 = model3.FindChildByName("AnimatedCube");
159 DALI_TEST_CHECK(meshActor3);
161 Renderer renderer3 = meshActor3.GetRendererAt(0u);
162 DALI_TEST_CHECK(renderer3);
164 // Check that model2 and model3 use the shared textures and geometries from the cache
165 DALI_TEST_EQUALS(renderer2.GetTextures(), renderer3.GetTextures(), TEST_LOCATION);
166 DALI_TEST_EQUALS(renderer2.GetGeometry(), renderer3.GetGeometry(), TEST_LOCATION);
168 // Destroy model2 and model3
175 application.SendNotification();
176 application.Render();
178 // All reference count should be decreased.
179 DALI_TEST_EQUALS(cacheManager.GetModelCacheRefCount(TEST_GLTF_FILE_NAME), 0u, TEST_LOCATION);
181 // Collect garbages hardly.
182 Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect(true);
183 Test::EmitGlobalTimerSignal();