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