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