Merge "Fix ZWJ, ZWNJ issues" into 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   // Create render target for the scene
81   Graphics::RenderTargetCreateInfo rtInfo{};
82   rtInfo.SetExtent({mSurfaceWidth, mSurfaceHeight});
83   mRenderTarget = mGraphicsController.CreateRenderTarget(rtInfo, nullptr);
84   mScene.SetSurfaceRenderTarget(mRenderTarget.get());
85 }
86
87 void TestApplication::InitializeCore()
88 {
89   mCore->SceneCreated();
90   mCore->Initialize();
91 }
92
93 TestApplication::~TestApplication()
94 {
95   Dali::Integration::Log::UninstallLogFunction();
96   delete mCore;
97 }
98
99 void TestApplication::LogContext(bool start, const char* tag)
100 {
101   if(start)
102   {
103     fprintf(stderr, "INFO: Trace Start: %s\n", tag);
104   }
105   else
106   {
107     fprintf(stderr, "INFO: Trace End: %s\n", tag);
108   }
109 }
110
111 void TestApplication::LogMessage(Dali::Integration::Log::DebugPriority level, std::string& message)
112 {
113   if(mLoggingEnabled)
114   {
115     switch(level)
116     {
117       case Dali::Integration::Log::DebugInfo:
118         fprintf(stderr, "INFO: %s", message.c_str());
119         break;
120       case Dali::Integration::Log::DebugWarning:
121         fprintf(stderr, "WARN: %s", message.c_str());
122         break;
123       case Dali::Integration::Log::DebugError:
124         fprintf(stderr, "ERROR: %s", message.c_str());
125         break;
126       default:
127         fprintf(stderr, "DEFAULT: %s", message.c_str());
128         break;
129     }
130   }
131 }
132
133 Dali::Integration::Core& TestApplication::GetCore()
134 {
135   return *mCore;
136 }
137
138 TestPlatformAbstraction& TestApplication::GetPlatform()
139 {
140   return mPlatformAbstraction;
141 }
142
143 TestRenderController& TestApplication::GetRenderController()
144 {
145   return mRenderController;
146 }
147
148 TestGraphicsController& TestApplication::GetGraphicsController()
149 {
150   return mGraphicsController;
151 }
152
153 TestGlAbstraction& TestApplication::GetGlAbstraction()
154 {
155   return static_cast<TestGlAbstraction&>(mGraphicsController.GetGlAbstraction());
156 }
157
158 TestGlContextHelperAbstraction& TestApplication::GetGlContextHelperAbstraction()
159 {
160   return static_cast<TestGlContextHelperAbstraction&>(mGraphicsController.GetGlContextHelperAbstraction());
161 }
162
163 TestGraphicsSyncImplementation& TestApplication::GetGraphicsSyncImpl()
164 {
165   return static_cast<TestGraphicsSyncImplementation&>(mGraphicsController.GetGraphicsSyncImpl());
166 }
167
168 void TestApplication::ProcessEvent(const Integration::Event& event)
169 {
170   mCore->QueueEvent(event);
171   mCore->ProcessEvents();
172 }
173
174 void TestApplication::SendNotification()
175 {
176   mCore->ProcessEvents();
177 }
178
179 void TestApplication::DoUpdate(uint32_t intervalMilliseconds, const char* location)
180 {
181   if(GetUpdateStatus() == 0 &&
182      mRenderStatus.NeedsUpdate() == false &&
183      !GetRenderController().WasCalled(TestRenderController::RequestUpdateFunc))
184   {
185     fprintf(stderr, "WARNING - Update not required :%s\n", location == NULL ? "NULL" : location);
186   }
187
188   uint32_t nextVSyncTime  = mLastVSyncTime + intervalMilliseconds;
189   float    elapsedSeconds = static_cast<float>(intervalMilliseconds) * 0.001f;
190
191   mCore->Update(elapsedSeconds, mLastVSyncTime, nextVSyncTime, mStatus, false, false);
192
193   GetRenderController().Initialize();
194
195   mLastVSyncTime = nextVSyncTime;
196 }
197
198 bool TestApplication::Render(uint32_t intervalMilliseconds, const char* location)
199 {
200   DoUpdate(intervalMilliseconds, location);
201
202   // Reset the status
203   mRenderStatus.SetNeedsUpdate(false);
204   mRenderStatus.SetNeedsPostRender(false);
205
206   mCore->PreRender(mRenderStatus, false /*do not force clear*/, false /*do not skip rendering*/);
207   mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/);
208   mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/);
209   mCore->PostRender(false /*do not skip rendering*/);
210
211   mFrame++;
212
213   return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate();
214 }
215
216 bool TestApplication::PreRenderWithPartialUpdate(uint32_t intervalMilliseconds, const char* location, std::vector<Rect<int>>& damagedRects)
217 {
218   DoUpdate(intervalMilliseconds, location);
219
220   mCore->PreRender(mRenderStatus, false /*do not force clear*/, false /*do not skip rendering*/);
221   mCore->PreRender(mScene, damagedRects);
222
223   return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate();
224 }
225
226 bool TestApplication::RenderWithPartialUpdate(std::vector<Rect<int>>& damagedRects, Rect<int>& clippingRect)
227 {
228   mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/, clippingRect);
229   mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/, clippingRect);
230   mCore->PostRender(false /*do not skip rendering*/);
231
232   mFrame++;
233
234   return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate();
235 }
236
237 uint32_t TestApplication::GetUpdateStatus()
238 {
239   return mStatus.KeepUpdating();
240 }
241
242 bool TestApplication::UpdateOnly(uint32_t intervalMilliseconds)
243 {
244   DoUpdate(intervalMilliseconds);
245   return mStatus.KeepUpdating();
246 }
247
248 bool TestApplication::GetRenderNeedsUpdate()
249 {
250   return mRenderStatus.NeedsUpdate();
251 }
252
253 bool TestApplication::GetRenderNeedsPostRender()
254 {
255   return mRenderStatus.NeedsPostRender();
256 }
257
258 bool TestApplication::RenderOnly()
259 {
260   // Update Time values
261   mCore->PreRender(mRenderStatus, false /*do not force clear*/, false /*do not skip rendering*/);
262   mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/);
263   mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/);
264   mCore->PostRender(false /*do not skip rendering*/);
265
266   mFrame++;
267
268   return mRenderStatus.NeedsUpdate();
269 }
270
271 void TestApplication::ResetContext()
272 {
273   mCore->ContextDestroyed();
274   mGraphicsController.Initialize();
275   mCore->ContextCreated();
276 }
277
278 uint32_t TestApplication::Wait(uint32_t durationToWait)
279 {
280   int time = 0;
281
282   for(uint32_t i = 0; i <= (durationToWait / RENDER_FRAME_INTERVAL); i++)
283   {
284     SendNotification();
285     Render(RENDER_FRAME_INTERVAL);
286     time += RENDER_FRAME_INTERVAL;
287   }
288   return time;
289 }
290
291 } // namespace Dali