Merge "Dont keep update unnecessarily running when even thread notifications are...
[platform/core/uifw/dali-core.git] / dali / internal / common / core-impl.cpp
1 /*
2  * Copyright (c) 2014 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
19 #include <dali/internal/common/core-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/integration-api/system-overlay.h>
23 #include <dali/integration-api/core.h>
24 #include <dali/integration-api/platform-abstraction.h>
25 #include <dali/integration-api/gl-sync-abstraction.h>
26 #include <dali/integration-api/render-controller.h>
27 #include <dali/internal/event/actors/actor-impl.h>
28 #include <dali/internal/event/common/stage-impl.h>
29 #include <dali/internal/event/animation/animation-playlist.h>
30 #include <dali/internal/event/common/property-notification-manager.h>
31 #include <dali/internal/event/common/notification-manager.h>
32 #include <dali/integration-api/events/event.h>
33 #include <dali/internal/event/events/event-processor.h>
34 #include <dali/internal/event/events/gesture-event-processor.h>
35 #include <dali/internal/update/manager/update-manager.h>
36 #include <dali/internal/render/common/performance-monitor.h>
37 #include <dali/internal/render/common/render-manager.h>
38 #include <dali/internal/update/common/discard-queue.h>
39 #include <dali/internal/common/event-to-update.h>
40 #include <dali/internal/update/resources/resource-manager.h>
41 #include <dali/internal/event/text/font-factory.h>
42 #include <dali/internal/event/images/image-factory.h>
43 #include <dali/internal/event/images/emoji-factory.h>
44 #include <dali/internal/event/modeling/model-factory.h>
45 #include <dali/internal/event/common/thread-local-storage.h>
46 #include <dali/internal/event/effects/shader-factory.h>
47 #include <dali/internal/update/touch/touch-resampler.h>
48 #include <dali/internal/event/common/type-registry-impl.h>
49
50 #include <dali/internal/render/gl-resources/texture-cache.h>
51 #include <dali/internal/render/gl-resources/context.h>
52
53 using Dali::Internal::SceneGraph::UpdateManager;
54 using Dali::Internal::SceneGraph::RenderManager;
55 using Dali::Internal::SceneGraph::DiscardQueue;
56 using Dali::Internal::SceneGraph::RenderQueue;
57 using Dali::Internal::SceneGraph::TextureCache;
58
59 // The Update for frame N+1 may be processed whilst frame N is being rendered.
60 static const unsigned int MAXIMUM_UPDATE_COUNT = 2u;
61
62 namespace Dali
63 {
64
65 namespace Internal
66 {
67
68 using Integration::RenderController;
69 using Integration::PlatformAbstraction;
70 using Integration::GlSyncAbstraction;
71 using Integration::GestureManager;
72 using Integration::GlAbstraction;
73 using Integration::Event;
74 using Integration::UpdateStatus;
75 using Integration::RenderStatus;
76
77 Core::Core( RenderController& renderController, PlatformAbstraction& platform,
78             GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction,
79             GestureManager& gestureManager)
80 : mRenderController( renderController ),
81   mPlatform(platform),
82   mGestureEventProcessor(NULL),
83   mEventProcessor(NULL),
84   mUpdateManager(NULL),
85   mRenderManager(NULL),
86   mDiscardQueue(NULL),
87   mResourcePostProcessQueue(),
88   mNotificationManager(NULL),
89   mFontFactory(NULL),
90   mImageFactory(NULL),
91   mModelFactory(NULL),
92   mShaderFactory(NULL),
93   mEmojiFactory(NULL),
94   mIsActive(true),
95   mProcessingEvent(false)
96 {
97   // Create the thread local storage
98   CreateThreadLocalStorage();
99
100   // This does nothing until Core is built with --enable-performance-monitor
101   PERFORMANCE_MONITOR_INIT( platform );
102
103   mNotificationManager = new NotificationManager();
104
105   mAnimationPlaylist = AnimationPlaylist::New();
106
107   mPropertyNotificationManager = PropertyNotificationManager::New();
108
109   std::vector< ResourcePostProcessRequest> init;
110   mResourcePostProcessQueue = new ResourcePostProcessList(init);
111
112   mRenderManager = RenderManager::New( glAbstraction, *mResourcePostProcessQueue );
113
114   RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
115   TextureCache& textureCache = mRenderManager->GetTextureCache();
116   mDiscardQueue = new DiscardQueue( renderQueue );
117
118   mResourceManager = new ResourceManager(  mPlatform,
119                                           *mNotificationManager,
120                                            textureCache,
121                                           *mResourcePostProcessQueue,
122                                           *mRenderManager,
123                                           *mDiscardQueue,
124                                            renderQueue );
125
126   mTouchResampler = TouchResampler::New();
127
128   mUpdateManager = new UpdateManager( *mNotificationManager,
129                                        glSyncAbstraction,
130                                       *mAnimationPlaylist,
131                                       *mPropertyNotificationManager,
132                                       *mResourceManager,
133                                       *mDiscardQueue,
134                                        renderController,
135                                       *mRenderManager,
136                                        renderQueue,
137                                        textureCache,
138                                       *mTouchResampler );
139
140   mResourceClient = new ResourceClient( *mResourceManager, *mUpdateManager );
141
142   mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager ) );
143
144   mStage->Initialize();
145
146   mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController);
147   mEventProcessor = new EventProcessor(*mStage, *mNotificationManager, *mGestureEventProcessor);
148
149   mFontFactory = new FontFactory(*mResourceClient);
150   mImageFactory = new ImageFactory( *mResourceClient );
151   mModelFactory = new ModelFactory(*mResourceClient);
152   mShaderFactory = new ShaderFactory(*mResourceClient);
153   mShaderFactory->LoadDefaultShaders();
154   mEmojiFactory = new EmojiFactory();
155
156   GetImplementation(Dali::TypeRegistry::Get()).CallInitFunctions();
157 }
158
159 Core::~Core()
160 {
161   /**
162    * TODO this should be done by Adaptor, Core does not know about threading
163    * First stop the resource loading thread(s)
164    */
165   mPlatform.JoinLoaderThreads();
166
167   /*
168    * The order of destructing these singletons is important!!!
169    */
170
171   // clear the thread local storage first
172   // allows core to be created / deleted many times in the same thread (how TET cases work).
173   // Do this before mStage.Reset() so Stage::IsInstalled() returns false
174   ThreadLocalStorage::Get().Remove();
175
176   // Clean-up stage - remove default camera and root layer
177   mStage->Uninitialize();
178
179   // remove (last?) reference to stage
180   mStage.Reset();
181
182   delete mEventProcessor;
183   delete mGestureEventProcessor;
184   delete mNotificationManager;
185   delete mFontFactory;
186   delete mImageFactory;
187   delete mModelFactory;
188   delete mShaderFactory;
189   delete mResourceClient;
190   delete mResourceManager;
191   delete mUpdateManager;
192   delete mTouchResampler;
193   delete mEmojiFactory;
194   delete mRenderManager;
195   delete mDiscardQueue;
196   delete mResourcePostProcessQueue;
197 }
198
199 void Core::ContextCreated()
200 {
201   mRenderManager->ContextCreated();
202 }
203
204 void Core::ContextToBeDestroyed()
205 {
206   mRenderManager->ContextDestroyed();
207 }
208
209 void Core::SurfaceResized(unsigned int width, unsigned int height)
210 {
211   mStage->SetSize(width, height);
212 }
213
214 void Core::SetDpi(unsigned int dpiHorizontal, unsigned int dpiVertical)
215 {
216   mPlatform.SetDpi( dpiHorizontal, dpiVertical  );
217   mFontFactory->SetDpi( dpiHorizontal, dpiVertical);
218   mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) );
219 }
220
221 void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status )
222 {
223   // set the time delta so adaptor can easily print FPS with a release build with 0 as
224   // it is cached by frametime
225   status.secondsFromLastFrame = elapsedSeconds;
226
227   // Render returns true when there are updates on the stage or one or more animations are completed.
228   // Use the estimated time diff till we render as the elapsed time.
229   status.keepUpdating = mUpdateManager->Update( elapsedSeconds,
230                                                 lastVSyncTimeMilliseconds,
231                                                 nextVSyncTimeMilliseconds );
232
233   // Check the Notification Manager message queue to set needsNotification
234   status.needsNotification = mNotificationManager->MessagesToProcess();
235
236   // No need to keep update running if there are notifications to process.
237   // Any message to update will wake it up anyways
238
239   if ( mResourceManager->ResourcesToProcess() )
240   {
241     // If we are still processing resources, then we have to continue the update
242     status.keepUpdating |= Integration::KeepUpdating::LOADING_RESOURCES;
243   }
244 }
245
246 void Core::Render( RenderStatus& status )
247 {
248   bool updateRequired = mRenderManager->Render( status );
249
250   status.SetNeedsUpdate( updateRequired );
251 }
252
253 void Core::Suspend()
254 {
255   mPlatform.Suspend();
256
257   mIsActive = false;
258 }
259
260 void Core::Resume()
261 {
262   mPlatform.Resume();
263
264   mIsActive = true;
265
266   // trigger processing of events queued up while paused
267   ProcessEvents();
268 }
269
270 void Core::QueueEvent( const Integration::Event& event )
271 {
272   mEventProcessor->QueueEvent( event );
273 }
274
275 void Core::ProcessEvents()
276 {
277   // Guard against calls to ProcessEvents() during ProcessEvents()
278   if( mProcessingEvent )
279   {
280     DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!" );
281     mRenderController.RequestProcessEventsOnIdle();
282     return;
283   }
284
285   mProcessingEvent = true;
286
287   EventToUpdate& eventToUpdate = mUpdateManager->GetEventToUpdate();
288
289   // Signal that any messages received will be flushed soon
290   eventToUpdate.EventProcessingStarted();
291
292   mEventProcessor->ProcessEvents();
293
294   mNotificationManager->ProcessMessages();
295
296   // Avoid allocating MessageBuffers, triggering size-negotiation or sending any other spam whilst paused
297   if( mIsActive )
298   {
299     // Emit signal here to start size negotiation and control relayout.
300     mStage->EmitEventProcessingFinishedSignal();
301
302     // Flush discard queue for image factory
303     mImageFactory->FlushReleaseQueue();
304
305     // send text requests if required
306     mFontFactory->SendTextRequests();
307
308     // Flush any queued messages for the update-thread
309     const bool messagesToProcess = eventToUpdate.FlushQueue();
310
311     // Check if the touch or gestures require updates.
312     const bool touchNeedsUpdate = mTouchResampler->NeedsUpdate();
313     const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
314
315     if( messagesToProcess || touchNeedsUpdate || gestureNeedsUpdate )
316     {
317       // tell the render controller to keep update thread running
318       mRenderController.RequestUpdate();
319     }
320   }
321
322   // ProcessEvents() may now be called again
323   mProcessingEvent = false;
324 }
325
326 void Core::UpdateTouchData(const Integration::TouchData& touch)
327 {
328   mTouchResampler->SendTouchData( touch );
329 }
330
331 unsigned int Core::GetMaximumUpdateCount() const
332 {
333   return MAXIMUM_UPDATE_COUNT;
334 }
335
336 Integration::SystemOverlay& Core::GetSystemOverlay()
337 {
338   return mStage->GetSystemOverlay();
339 }
340
341 void Core::SetViewMode( ViewMode viewMode )
342 {
343   mStage->SetViewMode( viewMode );
344 }
345
346 ViewMode Core::GetViewMode() const
347 {
348   return mStage->GetViewMode();
349 }
350
351 void Core::SetStereoBase( float stereoBase )
352 {
353   mStage->SetStereoBase( stereoBase );
354 }
355
356 float Core::GetStereoBase() const
357 {
358   return mStage->GetStereoBase();
359 }
360
361 StagePtr Core::GetCurrentStage()
362 {
363   return mStage.Get();
364 }
365
366 PlatformAbstraction& Core::GetPlatform()
367 {
368   return mPlatform;
369 }
370
371 UpdateManager& Core::GetUpdateManager()
372 {
373   return *(mUpdateManager);
374 }
375
376 RenderManager& Core::GetRenderManager()
377 {
378   return *(mRenderManager);
379 }
380
381 NotificationManager& Core::GetNotificationManager()
382 {
383   return *(mNotificationManager);
384 }
385
386 ResourceManager& Core::GetResourceManager()
387 {
388   return *(mResourceManager);
389 }
390
391 ResourceClient& Core::GetResourceClient()
392 {
393   return *(mResourceClient);
394 }
395
396 FontFactory& Core::GetFontFactory()
397 {
398   return *(mFontFactory);
399 }
400
401 ImageFactory& Core::GetImageFactory()
402 {
403   return *(mImageFactory);
404 }
405
406 ModelFactory& Core::GetModelFactory()
407 {
408   return *(mModelFactory);
409 }
410
411 ShaderFactory& Core::GetShaderFactory()
412 {
413   return *(mShaderFactory);
414 }
415
416 GestureEventProcessor& Core::GetGestureEventProcessor()
417 {
418   return *(mGestureEventProcessor);
419 }
420
421 EmojiFactory& Core::GetEmojiFactory()
422 {
423   return *mEmojiFactory;
424 }
425
426 void Core::CreateThreadLocalStorage()
427 {
428   // a pointer to the ThreadLocalStorage object will be stored in TLS
429   // and automatically deleted when the thread is killed
430   new ThreadLocalStorage(this);
431 }
432
433 } // namespace Internal
434
435 } // namespace Dali