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