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