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