Dali 3D User Interface Engine
single-thread-controller.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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 // CLASS HEADER
20 
21 // EXTERNAL INCLUDES
22 #include <iostream>
24 
25 // INTERNAL INCLUDES
28 #include <base/time-service.h>
29 
30 namespace Dali
31 {
32 
33 namespace Internal
34 {
35 
36 namespace Adaptor
37 {
38 
39 namespace
40 {
41 const unsigned int MILLISECONDS_PER_FRAME = 17u;
42 const float SECONDS_PER_FRAME = MILLISECONDS_PER_FRAME * 0.001f;
43 
44 const unsigned int NANOSECONDS_PER_MICROSECOND( 1000u );
45 const float NANOSECONDS_TO_SECONDS( 1e-9f );
46 
47 #if defined(DEBUG_ENABLED)
48 Integration::Log::Filter* gLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_THREAD_SYNC");
49 #endif
50 
51 } // unnamed namespace
52 
56  mTimer(),
57  mFpsTracker( environmentOptions ),
58  mUpdateStatusLogger( environmentOptions ),
59  mRenderHelper( adaptorInterfaces ),
60  mCore( adaptorInterfaces.GetCore()),
61  mPerformanceInterface( adaptorInterfaces.GetPerformanceInterface() ),
62  mLastUpdateRenderTime( 0 ),
63  mSystemTime( 0 ),
64  mRefreshRate( environmentOptions.GetRenderRefreshRate() ),
65  mState( State::STOPPED ),
66  mUpdatingAndRendering( false ),
67  mStopRequestedWhileRendering( false )
68 {
69  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
70 }
71 
73 {
74  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
75 
76  Stop();
77 }
78 
80 {
81  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
82 
84 
85  // Create a tick-signal so that we can update and render every frame
87 }
88 
90 {
91  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
92 
95 
96  // tell core it has a context
98 
99  // Do an update/render straight away
101  UpdateRender( false );
102 
104 }
105 
107 {
108  if( mState == State::RUNNING )
109  {
110  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
111 
113 
115  }
116 }
117 
119 {
120  if( mState == State::PAUSED )
121  {
122  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
123 
124  // Do an update/render straight away
126  UpdateRender( false );
127 
129 
131  }
132 }
133 
135 {
136  if( mState != State::STOPPED )
137  {
138  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
139 
141 
143  {
144  // If we interrupted an update/render for this stop, then we should NOT terminate GL just yet
146  }
147  else
148  {
149  StopRendering();
150  }
151  }
152 }
153 
155 {
156  if( mState == State::SLEEPING )
157  {
158  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
159 
160  // Do an update/render straight away
162  UpdateRender( false );
163 
165  }
166 }
167 
169 {
171  {
172  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
173 
174  // Just do one update and render
175 
178 
179  Integration::RenderStatus renderStatus;
181  mCore.Render( renderStatus );
182  if( renderStatus.HasRendered() )
183  {
185  }
186  }
187 }
188 
189 void SingleThreadController::ReplaceSurface( RenderSurface* newSurface )
190 {
191  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
192  mRenderHelper.ReplaceSurface( newSurface );
193 }
194 
195 void SingleThreadController::SetRenderRefreshRate( unsigned int refreshRate )
196 {
197  if ( refreshRate != mRefreshRate )
198  {
199  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
200 
201  mRefreshRate = refreshRate;
202 
203  if( mTimer )
204  {
206  }
207  }
208 }
209 
211 {
212  DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ );
213 
214  if( mState == State::RUNNING )
215  {
216  UpdateRender( true );
217  }
218  else if( mState == State::STOPPED &&
220  {
221  DALI_LOG_INFO( gLogFilter, Debug::General, "%s(): STOPPING\n", __FUNCTION__ );
222 
223  StopRendering();
224 
226 
227  return false; // Stop the timer
228  }
229  return true;
230 }
231 
232 void SingleThreadController::UpdateRender( bool incrementTime )
233 {
234  DALI_LOG_INFO( gLogFilter, Debug::General, "%s():START\n", __FUNCTION__ );
235 
236  mUpdatingAndRendering = true;
237 
238  float lastFrameDelta( 0.0f );
239 
240  if( incrementTime )
241  {
242  // Use our usual time per frame for smoother animations rather than the real elapsed time
243 
244  lastFrameDelta = mRefreshRate * SECONDS_PER_FRAME;
246  }
247 
248  Integration::UpdateStatus updateStatus;
252 
254 
255  unsigned int keepUpdatingStatus = updateStatus.KeepUpdating();
256 
257  // Optional logging of update/render status
258  mUpdateStatusLogger.Log( keepUpdatingStatus );
259 
260  // Ensure we did not get interrupted an STOPPED
261  if( mState != State::STOPPED )
262  {
265 
266  Integration::RenderStatus renderStatus;
268  mCore.Render( renderStatus );
270 
271  if( renderStatus.HasRendered() )
272  {
274  }
275 
276  if( ! keepUpdatingStatus &&
277  ! renderStatus.NeedsUpdate() )
278  {
280  }
281  }
282 
283  mUpdatingAndRendering = false;
284 
285  DALI_LOG_INFO( gLogFilter, Debug::General, "%s():END\n", __FUNCTION__ );
286 }
287 
289 {
290  float timeSinceLastRender = 0.0f;
291 
292  // No need calculating if FPS tracking is NOT enabled
293  if( mFpsTracker.Enabled() )
294  {
295  uint64_t currentTime = 0;
296  TimeService::GetNanoseconds( currentTime );
297 
298  uint64_t delta = currentTime - mSystemTime;
299  mSystemTime = currentTime;
300 
301  timeSinceLastRender = delta * NANOSECONDS_TO_SECONDS;
302  }
303 
304  return timeSinceLastRender;
305 }
306 
307 
309 {
311  {
313  }
314 }
315 
317 {
318  mState = state;
319 
320  switch( state )
321  {
322  case State::RUNNING:
323  {
324  mTimer.Start();
325  break;
326  }
327 
328  case State::STOPPED:
329  case State::PAUSED:
330  case State::SLEEPING:
331  {
332  mTimer.Stop();
333  }
334  }
335 }
336 
338 {
340 
341  // Inform core of context destruction & shutdown EGL
344 }
345 
346 } // namespace Adaptor
347 
348 } // namespace Internal
349 
350 } // namespace Dali
Dali Docs Home
Read more about Dali