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