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