Merge "Klockwork fixes: Distance field iteration Checking for null...
[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::QueueEvent( const Integration::Event& event )
302 {
303   mEventProcessor->QueueEvent( event );
304 }
305
306 void Core::ProcessEvents()
307 {
308   // Guard against calls to ProcessEvents() during ProcessEvents()
309   if( mProcessingEvent )
310   {
311     DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!" );
312     mRenderController.RequestProcessEventsOnIdle();
313     return;
314   }
315
316   mProcessingEvent = true;
317
318   EventToUpdate& eventToUpdate = mUpdateManager->GetEventToUpdate();
319
320   // Signal that any messages received will be flushed soon
321   eventToUpdate.EventProcessingStarted();
322
323   mEventProcessor->ProcessEvents();
324
325   mNotificationManager->ProcessMessages();
326
327   // Avoid allocating MessageBuffers, triggering size-negotiation or sending any other spam whilst paused
328   if( mIsActive )
329   {
330     // Emit signal here to start size negotiation and control relayout.
331     mStage->EmitEventProcessingFinishedSignal();
332
333     // Flush discard queue for image factory
334     mImageFactory->FlushReleaseQueue();
335
336     // send text requests if required
337     mFontFactory->SendTextRequests();
338
339     // Flush any queued messages for the update-thread
340     const bool messagesToProcess = eventToUpdate.FlushQueue();
341
342     // Check if the touch or gestures require updates.
343     const bool touchNeedsUpdate = mTouchResampler->NeedsUpdate();
344     const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
345
346     if( messagesToProcess || touchNeedsUpdate || gestureNeedsUpdate )
347     {
348       // tell the render controller to keep update thread running
349       mRenderController.RequestUpdate();
350     }
351   }
352
353   // ProcessEvents() may now be called again
354   mProcessingEvent = false;
355 }
356
357 void Core::UpdateTouchData(const Integration::TouchData& touch)
358 {
359   mTouchResampler->SendTouchData( touch );
360 }
361
362 unsigned int Core::GetMaximumUpdateCount() const
363 {
364   return MAXIMUM_UPDATE_COUNT;
365 }
366
367 Integration::SystemOverlay& Core::GetSystemOverlay()
368 {
369   return mStage->GetSystemOverlay();
370 }
371
372 void Core::SetViewMode( ViewMode viewMode )
373 {
374   mStage->SetViewMode( viewMode );
375 }
376
377 ViewMode Core::GetViewMode() const
378 {
379   return mStage->GetViewMode();
380 }
381
382 void Core::SetStereoBase( float stereoBase )
383 {
384   mStage->SetStereoBase( stereoBase );
385 }
386
387 float Core::GetStereoBase() const
388 {
389   return mStage->GetStereoBase();
390 }
391
392 StagePtr Core::GetCurrentStage()
393 {
394   return mStage.Get();
395 }
396
397 PlatformAbstraction& Core::GetPlatform()
398 {
399   return mPlatform;
400 }
401
402 UpdateManager& Core::GetUpdateManager()
403 {
404   return *(mUpdateManager);
405 }
406
407 RenderManager& Core::GetRenderManager()
408 {
409   return *(mRenderManager);
410 }
411
412 NotificationManager& Core::GetNotificationManager()
413 {
414   return *(mNotificationManager);
415 }
416
417 ResourceManager& Core::GetResourceManager()
418 {
419   return *(mResourceManager);
420 }
421
422 ResourceClient& Core::GetResourceClient()
423 {
424   return *(mResourceClient);
425 }
426
427 FontFactory& Core::GetFontFactory()
428 {
429   return *(mFontFactory);
430 }
431
432 ImageFactory& Core::GetImageFactory()
433 {
434   return *(mImageFactory);
435 }
436
437 ModelFactory& Core::GetModelFactory()
438 {
439   return *(mModelFactory);
440 }
441
442 ShaderFactory& Core::GetShaderFactory()
443 {
444   return *(mShaderFactory);
445 }
446
447 GestureEventProcessor& Core::GetGestureEventProcessor()
448 {
449   return *(mGestureEventProcessor);
450 }
451
452 EmojiFactory& Core::GetEmojiFactory()
453 {
454   return *mEmojiFactory;
455 }
456
457 void Core::CreateThreadLocalStorage()
458 {
459   // a pointer to the ThreadLocalStorage object will be stored in TLS
460   // and automatically deleted when the thread is killed
461   new ThreadLocalStorage(this);
462 }
463
464 } // namespace Internal
465
466 } // namespace Dali