[dali_2.0.15] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-application.cpp
1 /*
2  * Copyright (c) 2021 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 #include "test-application.h"
19
20 namespace Dali
21 {
22 bool TestApplication::mLoggingEnabled = true;
23
24 TestApplication::TestApplication(uint32_t surfaceWidth,
25                                  uint32_t surfaceHeight,
26                                  uint32_t horizontalDpi,
27                                  uint32_t verticalDpi,
28                                  bool     initialize,
29                                  bool     enablePartialUpdate)
30 : mCore(NULL),
31   mSurfaceWidth(surfaceWidth),
32   mSurfaceHeight(surfaceHeight),
33   mFrame(0u),
34   mDpi{horizontalDpi, verticalDpi},
35   mLastVSyncTime(0u),
36   mPartialUpdateEnabled(enablePartialUpdate)
37 {
38   if(initialize)
39   {
40     Initialize();
41   }
42 }
43
44 void TestApplication::Initialize()
45 {
46   CreateCore();
47   CreateScene();
48   InitializeCore();
49 }
50
51 void TestApplication::CreateCore()
52 {
53   // We always need the first update!
54   mStatus.keepUpdating = Integration::KeepUpdating::STAGE_KEEP_RENDERING;
55
56   mCore = Dali::Integration::Core::New(mRenderController,
57                                        mPlatformAbstraction,
58                                        mGraphicsController,
59                                        Integration::RenderToFrameBuffer::FALSE,
60                                        Integration::DepthBufferAvailable::TRUE,
61                                        Integration::StencilBufferAvailable::TRUE,
62                                        mPartialUpdateEnabled ? Integration::PartialUpdateAvailable::TRUE : Integration::PartialUpdateAvailable::FALSE);
63
64   mCore->ContextCreated();
65
66   Dali::Integration::Log::LogFunction logFunction(&TestApplication::LogMessage);
67   Dali::Integration::Log::InstallLogFunction(logFunction);
68
69   Dali::Integration::Trace::LogContextFunction logContextFunction(&TestApplication::LogContext);
70   Dali::Integration::Trace::InstallLogContextFunction(logContextFunction);
71
72   Dali::Integration::Trace::LogContext(true, "Test");
73 }
74
75 void TestApplication::CreateScene()
76 {
77   mScene = Dali::Integration::Scene::New(Size(static_cast<float>(mSurfaceWidth), static_cast<float>(mSurfaceHeight)));
78   mScene.SetDpi(Vector2(static_cast<float>(mDpi.x), static_cast<float>(mDpi.y)));
79 }
80
81 void TestApplication::InitializeCore()
82 {
83   mCore->SceneCreated();
84   mCore->Initialize();
85 }
86
87 TestApplication::~TestApplication()
88 {
89   Dali::Integration::Log::UninstallLogFunction();
90   delete mCore;
91 }
92
93 void TestApplication::LogContext(bool start, const char* tag)
94 {
95   if(start)
96   {
97     fprintf(stderr, "INFO: Trace Start: %s\n", tag);
98   }
99   else
100   {
101     fprintf(stderr, "INFO: Trace End: %s\n", tag);
102   }
103 }
104
105 void TestApplication::LogMessage(Dali::Integration::Log::DebugPriority level, std::string& message)
106 {
107   if(mLoggingEnabled)
108   {
109     switch(level)
110     {
111       case Dali::Integration::Log::DebugInfo:
112         fprintf(stderr, "INFO: %s", message.c_str());
113         break;
114       case Dali::Integration::Log::DebugWarning:
115         fprintf(stderr, "WARN: %s", message.c_str());
116         break;
117       case Dali::Integration::Log::DebugError:
118         fprintf(stderr, "ERROR: %s", message.c_str());
119         break;
120       default:
121         fprintf(stderr, "DEFAULT: %s", message.c_str());
122         break;
123     }
124   }
125 }
126
127 Dali::Integration::Core& TestApplication::GetCore()
128 {
129   return *mCore;
130 }
131
132 TestPlatformAbstraction& TestApplication::GetPlatform()
133 {
134   return mPlatformAbstraction;
135 }
136
137 TestRenderController& TestApplication::GetRenderController()
138 {
139   return mRenderController;
140 }
141
142 TestGraphicsController& TestApplication::GetGraphicsController()
143 {
144   return mGraphicsController;
145 }
146
147 TestGlAbstraction& TestApplication::GetGlAbstraction()
148 {
149   return static_cast<TestGlAbstraction&>(mGraphicsController.GetGlAbstraction());
150 }
151
152 TestGlSyncAbstraction& TestApplication::GetGlSyncAbstraction()
153 {
154   return static_cast<TestGlSyncAbstraction&>(mGraphicsController.GetGlSyncAbstraction());
155 }
156
157 TestGlContextHelperAbstraction& TestApplication::GetGlContextHelperAbstraction()
158 {
159   return static_cast<TestGlContextHelperAbstraction&>(mGraphicsController.GetGlContextHelperAbstraction());
160 }
161
162 void TestApplication::ProcessEvent(const Integration::Event& event)
163 {
164   mCore->QueueEvent(event);
165   mCore->ProcessEvents();
166 }
167
168 void TestApplication::SendNotification()
169 {
170   mCore->ProcessEvents();
171 }
172
173 void TestApplication::DoUpdate(uint32_t intervalMilliseconds, const char* location)
174 {
175   if(GetUpdateStatus() == 0 &&
176      mRenderStatus.NeedsUpdate() == false &&
177      !GetRenderController().WasCalled(TestRenderController::RequestUpdateFunc))
178   {
179     fprintf(stderr, "WARNING - Update not required :%s\n", location == NULL ? "NULL" : location);
180   }
181
182   uint32_t nextVSyncTime  = mLastVSyncTime + intervalMilliseconds;
183   float    elapsedSeconds = static_cast<float>(intervalMilliseconds) * 0.001f;
184
185   mCore->Update(elapsedSeconds, mLastVSyncTime, nextVSyncTime, mStatus, false, false);
186
187   GetRenderController().Initialize();
188
189   mLastVSyncTime = nextVSyncTime;
190 }
191
192 bool TestApplication::Render(uint32_t intervalMilliseconds, const char* location)
193 {
194   DoUpdate(intervalMilliseconds, location);
195
196   // Reset the status
197   mRenderStatus.SetNeedsUpdate(false);
198   mRenderStatus.SetNeedsPostRender(false);
199
200   mCore->PreRender(mRenderStatus, false /*do not force clear*/, false /*do not skip rendering*/);
201   mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/);
202   mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/);
203   mCore->PostRender(false /*do not skip rendering*/);
204
205   mFrame++;
206
207   return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate();
208 }
209
210 bool TestApplication::PreRenderWithPartialUpdate(uint32_t intervalMilliseconds, const char* location, std::vector<Rect<int>>& damagedRects)
211 {
212   DoUpdate(intervalMilliseconds, location);
213
214   mCore->PreRender(mRenderStatus, false /*do not force clear*/, false /*do not skip rendering*/);
215   mCore->PreRender(mScene, damagedRects);
216
217   return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate();
218 }
219
220 bool TestApplication::RenderWithPartialUpdate(std::vector<Rect<int>>& damagedRects, Rect<int>& clippingRect)
221 {
222   mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/, clippingRect);
223   mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/, clippingRect);
224   mCore->PostRender(false /*do not skip rendering*/);
225
226   mFrame++;
227
228   return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate();
229 }
230
231 uint32_t TestApplication::GetUpdateStatus()
232 {
233   return mStatus.KeepUpdating();
234 }
235
236 bool TestApplication::UpdateOnly(uint32_t intervalMilliseconds)
237 {
238   DoUpdate(intervalMilliseconds);
239   return mStatus.KeepUpdating();
240 }
241
242 bool TestApplication::GetRenderNeedsUpdate()
243 {
244   return mRenderStatus.NeedsUpdate();
245 }
246
247 bool TestApplication::GetRenderNeedsPostRender()
248 {
249   return mRenderStatus.NeedsPostRender();
250 }
251
252 bool TestApplication::RenderOnly()
253 {
254   // Update Time values
255   mCore->PreRender(mRenderStatus, false /*do not force clear*/, false /*do not skip rendering*/);
256   mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/);
257   mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/);
258   mCore->PostRender(false /*do not skip rendering*/);
259
260   mFrame++;
261
262   return mRenderStatus.NeedsUpdate();
263 }
264
265 void TestApplication::ResetContext()
266 {
267   mCore->ContextDestroyed();
268   mGraphicsController.Initialize();
269   mCore->ContextCreated();
270 }
271
272 uint32_t TestApplication::Wait(uint32_t durationToWait)
273 {
274   int time = 0;
275
276   for(uint32_t i = 0; i <= (durationToWait / RENDER_FRAME_INTERVAL); i++)
277   {
278     SendNotification();
279     Render(RENDER_FRAME_INTERVAL);
280     time += RENDER_FRAME_INTERVAL;
281   }
282   return time;
283 }
284
285 } // namespace Dali