8effd3f0f9b140d6a65b627ba6c5a36277e5895e
[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/common/thread-local-storage.h>
46 #include <dali/internal/event/effects/shader-factory.h>
47 #include <dali/internal/update/touch/touch-resampler.h>
48 #include <dali/internal/event/common/type-registry-impl.h>
49 #include <dali/internal/event/render-tasks/render-task-list-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   mResourceClient = new ResourceClient( *mResourceManager, *mUpdateManager, dataRetentionPolicy );
156
157   mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager ) );
158
159   mStage->Initialize();
160
161   mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController);
162   mEventProcessor = new EventProcessor(*mStage, *mNotificationManager, *mGestureEventProcessor);
163
164   mFontFactory = new FontFactory(*mResourceClient);
165   mImageFactory = new ImageFactory( *mResourceClient );
166   mShaderFactory = new ShaderFactory(*mResourceClient);
167   mShaderFactory->LoadDefaultShaders();
168   mEmojiFactory = new EmojiFactory();
169
170   GetImplementation(Dali::TypeRegistry::Get()).CallInitFunctions();
171 }
172
173 Core::~Core()
174 {
175   /**
176    * TODO this should be done by Adaptor, Core does not know about threading
177    * First stop the resource loading thread(s)
178    */
179   mPlatform.JoinLoaderThreads();
180
181   /*
182    * The order of destructing these singletons is important!!!
183    */
184
185   // clear the thread local storage first
186   // allows core to be created / deleted many times in the same thread (how TET cases work).
187   // Do this before mStage.Reset() so Stage::IsInstalled() returns false
188   ThreadLocalStorage::Get().Remove();
189
190   // Clean-up stage - remove default camera and root layer
191   mStage->Uninitialize();
192
193   // remove (last?) reference to stage
194   mStage.Reset();
195
196   delete mEventProcessor;
197   delete mGestureEventProcessor;
198   delete mNotificationManager;
199   delete mFontFactory;
200   delete mImageFactory;
201   delete mShaderFactory;
202   delete mResourceClient;
203   delete mResourceManager;
204   delete mUpdateManager;
205   delete mTouchResampler;
206   delete mEmojiFactory;
207   delete mRenderManager;
208   delete mDiscardQueue;
209   delete mResourcePostProcessQueue;
210 }
211
212 Integration::ContextNotifierInterface* Core::GetContextNotifier()
213 {
214   return mStage.Get();
215 }
216
217 void Core::RecoverFromContextLoss()
218 {
219   DALI_LOG_INFO(gCoreFilter, Debug::Verbose, "Core::RecoverFromContextLoss()\n");
220
221   mImageFactory->RecoverFromContextLoss(); // Reload images from files
222   mFontFactory->RecoverFromContextLoss();  // Reload glyphs from cache into new atlas
223   mStage->GetRenderTaskList().RecoverFromContextLoss(); // Re-trigger render-tasks
224 }
225
226 void Core::ContextCreated()
227 {
228   mRenderManager->ContextCreated();
229 }
230
231 void Core::ContextDestroyed()
232 {
233   mRenderManager->ContextDestroyed();
234 }
235
236 void Core::SurfaceResized(unsigned int width, unsigned int height)
237 {
238   mStage->SetSize(width, height);
239 }
240
241 void Core::SetDpi(unsigned int dpiHorizontal, unsigned int dpiVertical)
242 {
243   mPlatform.SetDpi( dpiHorizontal, dpiVertical );
244   mFontFactory->SetDpi( dpiHorizontal, dpiVertical);
245   mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) );
246 }
247
248 void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status )
249 {
250   // set the time delta so adaptor can easily print FPS with a release build with 0 as
251   // it is cached by frametime
252   status.secondsFromLastFrame = elapsedSeconds;
253
254   // Render returns true when there are updates on the stage or one or more animations are completed.
255   // Use the estimated time diff till we render as the elapsed time.
256   status.keepUpdating = mUpdateManager->Update( elapsedSeconds,
257                                                 lastVSyncTimeMilliseconds,
258                                                 nextVSyncTimeMilliseconds );
259
260   // Check the Notification Manager message queue to set needsNotification
261   status.needsNotification = mNotificationManager->MessagesToProcess();
262
263   // No need to keep update running if there are notifications to process.
264   // Any message to update will wake it up anyways
265
266   if ( mResourceManager->ResourcesToProcess() )
267   {
268     // If we are still processing resources, then we have to continue the update
269     status.keepUpdating |= Integration::KeepUpdating::LOADING_RESOURCES;
270   }
271 }
272
273 void Core::Render( RenderStatus& status )
274 {
275   bool updateRequired = mRenderManager->Render( status );
276
277   status.SetNeedsUpdate( updateRequired );
278 }
279
280 void Core::Suspend()
281 {
282   mPlatform.Suspend();
283
284   mIsActive = false;
285 }
286
287 void Core::Resume()
288 {
289   mPlatform.Resume();
290
291   mIsActive = true;
292
293   // trigger processing of events queued up while paused
294   ProcessEvents();
295 }
296
297 void Core::SceneCreated()
298 {
299   mStage->EmitSceneCreatedSignal();
300 }
301
302 void Core::QueueEvent( const Integration::Event& event )
303 {
304   mEventProcessor->QueueEvent( event );
305 }
306
307 void Core::ProcessEvents()
308 {
309   // Guard against calls to ProcessEvents() during ProcessEvents()
310   if( mProcessingEvent )
311   {
312     DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!" );
313     mRenderController.RequestProcessEventsOnIdle();
314     return;
315   }
316
317   mProcessingEvent = true;
318
319   EventToUpdate& eventToUpdate = mUpdateManager->GetEventToUpdate();
320
321   // Signal that any messages received will be flushed soon
322   eventToUpdate.EventProcessingStarted();
323
324   mEventProcessor->ProcessEvents();
325
326   mNotificationManager->ProcessMessages();
327
328   // Avoid allocating MessageBuffers, triggering size-negotiation or sending any other spam whilst paused
329   if( mIsActive )
330   {
331     // Emit signal here to start size negotiation and control relayout.
332     mStage->EmitEventProcessingFinishedSignal();
333
334     // Flush discard queue for image factory
335     mImageFactory->FlushReleaseQueue();
336
337     // send text requests if required
338     mFontFactory->SendTextRequests();
339
340     // Flush any queued messages for the update-thread
341     const bool messagesToProcess = eventToUpdate.FlushQueue();
342
343     // Check if the touch or gestures require updates.
344     const bool touchNeedsUpdate = mTouchResampler->NeedsUpdate();
345     const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
346
347     if( messagesToProcess || touchNeedsUpdate || gestureNeedsUpdate )
348     {
349       // tell the render controller to keep update thread running
350       mRenderController.RequestUpdate();
351     }
352   }
353
354   // ProcessEvents() may now be called again
355   mProcessingEvent = false;
356 }
357
358 void Core::UpdateTouchData(const Integration::TouchData& touch)
359 {
360   mTouchResampler->SendTouchData( touch );
361 }
362
363 unsigned int Core::GetMaximumUpdateCount() const
364 {
365   return MAXIMUM_UPDATE_COUNT;
366 }
367
368 Integration::SystemOverlay& Core::GetSystemOverlay()
369 {
370   return mStage->GetSystemOverlay();
371 }
372
373 void Core::SetViewMode( ViewMode viewMode )
374 {
375   mStage->SetViewMode( viewMode );
376 }
377
378 ViewMode Core::GetViewMode() const
379 {
380   return mStage->GetViewMode();
381 }
382
383 void Core::SetStereoBase( float stereoBase )
384 {
385   mStage->SetStereoBase( stereoBase );
386 }
387
388 float Core::GetStereoBase() const
389 {
390   return mStage->GetStereoBase();
391 }
392
393 StagePtr Core::GetCurrentStage()
394 {
395   return mStage.Get();
396 }
397
398 PlatformAbstraction& Core::GetPlatform()
399 {
400   return mPlatform;
401 }
402
403 UpdateManager& Core::GetUpdateManager()
404 {
405   return *(mUpdateManager);
406 }
407
408 RenderManager& Core::GetRenderManager()
409 {
410   return *(mRenderManager);
411 }
412
413 NotificationManager& Core::GetNotificationManager()
414 {
415   return *(mNotificationManager);
416 }
417
418 ResourceManager& Core::GetResourceManager()
419 {
420   return *(mResourceManager);
421 }
422
423 ResourceClient& Core::GetResourceClient()
424 {
425   return *(mResourceClient);
426 }
427
428 FontFactory& Core::GetFontFactory()
429 {
430   return *(mFontFactory);
431 }
432
433 ImageFactory& Core::GetImageFactory()
434 {
435   return *(mImageFactory);
436 }
437
438 ShaderFactory& Core::GetShaderFactory()
439 {
440   return *(mShaderFactory);
441 }
442
443 GestureEventProcessor& Core::GetGestureEventProcessor()
444 {
445   return *(mGestureEventProcessor);
446 }
447
448 EmojiFactory& Core::GetEmojiFactory()
449 {
450   return *mEmojiFactory;
451 }
452
453 void Core::CreateThreadLocalStorage()
454 {
455   // a pointer to the ThreadLocalStorage object will be stored in TLS
456   // and automatically deleted when the thread is killed
457   new ThreadLocalStorage(this);
458 }
459
460 } // namespace Internal
461
462 } // namespace Dali