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