Merge "Add missed doxygen documentation" 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->SurfaceResized( width, height );
253
254   // The stage-size may be less than surface-size (reduced by top-margin)
255   Vector2 size = mStage->GetSize();
256   mRelayoutController->SetStageSize( size.width, size.height );
257 }
258
259 void Core::SetTopMargin( unsigned int margin )
260 {
261   mStage->SetTopMargin( margin );
262
263   // The stage-size may be less than surface-size (reduced by top-margin)
264   Vector2 size = mStage->GetSize();
265   mRelayoutController->SetStageSize( size.width, size.height );
266 }
267
268 void Core::SetDpi( unsigned int dpiHorizontal, unsigned int dpiVertical )
269 {
270   mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) );
271 }
272
273 void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status )
274 {
275   // set the time delta so adaptor can easily print FPS with a release build with 0 as
276   // it is cached by frametime
277   status.secondsFromLastFrame = elapsedSeconds;
278
279   // Render returns true when there are updates on the stage or one or more animations are completed.
280   // Use the estimated time diff till we render as the elapsed time.
281   status.keepUpdating = mUpdateManager->Update( elapsedSeconds,
282                                                 lastVSyncTimeMilliseconds,
283                                                 nextVSyncTimeMilliseconds );
284
285   // Check the Notification Manager message queue to set needsNotification
286   status.needsNotification = mNotificationManager->MessagesToProcess();
287
288   // No need to keep update running if there are notifications to process.
289   // Any message to update will wake it up anyways
290
291   if ( mResourceManager->ResourcesToProcess() )
292   {
293     // If we are still processing resources, then we have to continue the update
294     status.keepUpdating |= Integration::KeepUpdating::LOADING_RESOURCES;
295   }
296 }
297
298 void Core::Render( RenderStatus& status )
299 {
300   bool updateRequired = mRenderManager->Render( status );
301
302   status.SetNeedsUpdate( updateRequired );
303 }
304
305 void Core::Suspend()
306 {
307   mPlatform.Suspend();
308
309   mIsActive = false;
310 }
311
312 void Core::Resume()
313 {
314   mPlatform.Resume();
315
316   mIsActive = true;
317
318   // trigger processing of events queued up while paused
319   ProcessEvents();
320 }
321
322 void Core::SceneCreated()
323 {
324   mStage->EmitSceneCreatedSignal();
325
326   mRelayoutController->OnApplicationSceneCreated();
327 }
328
329 void Core::QueueEvent( const Integration::Event& event )
330 {
331   mEventProcessor->QueueEvent( event );
332 }
333
334 void Core::ProcessEvents()
335 {
336   // Guard against calls to ProcessEvents() during ProcessEvents()
337   if( mProcessingEvent )
338   {
339     DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!\n" );
340     mRenderController.RequestProcessEventsOnIdle();
341     return;
342   }
343
344   mProcessingEvent = true;
345   mRelayoutController->SetProcessingCoreEvents( true );
346
347   // Signal that any messages received will be flushed soon
348   mUpdateManager->EventProcessingStarted();
349
350   mEventProcessor->ProcessEvents();
351
352   mNotificationManager->ProcessMessages();
353
354   // Avoid allocating MessageBuffers, triggering size-negotiation or sending any other spam whilst paused
355   if( mIsActive )
356   {
357     // Emit signal here to start size negotiation and control relayout.
358     mStage->EmitEventProcessingFinishedSignal();
359
360     // Run the size negotiation after event processing finished signal
361     mRelayoutController->Relayout();
362
363     // Flush discard queue for image factory
364     mImageFactory->FlushReleaseQueue();
365
366     // Flush any queued messages for the update-thread
367     const bool messagesToProcess = mUpdateManager->FlushQueue();
368
369     // Check if the touch or gestures require updates.
370     const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
371
372     if( messagesToProcess || gestureNeedsUpdate )
373     {
374       // tell the render controller to keep update thread running
375       mRenderController.RequestUpdate();
376     }
377   }
378
379   mRelayoutController->SetProcessingCoreEvents( false );
380
381   // ProcessEvents() may now be called again
382   mProcessingEvent = false;
383 }
384
385 unsigned int Core::GetMaximumUpdateCount() const
386 {
387   return MAXIMUM_UPDATE_COUNT;
388 }
389
390 Integration::SystemOverlay& Core::GetSystemOverlay()
391 {
392   return mStage->GetSystemOverlay();
393 }
394
395 void Core::SetViewMode( ViewMode viewMode )
396 {
397   mStage->SetViewMode( viewMode );
398 }
399
400 ViewMode Core::GetViewMode() const
401 {
402   return mStage->GetViewMode();
403 }
404
405 void Core::SetStereoBase( float stereoBase )
406 {
407   mStage->SetStereoBase( stereoBase );
408 }
409
410 float Core::GetStereoBase() const
411 {
412   return mStage->GetStereoBase();
413 }
414
415 StagePtr Core::GetCurrentStage()
416 {
417   return mStage.Get();
418 }
419
420 PlatformAbstraction& Core::GetPlatform()
421 {
422   return mPlatform;
423 }
424
425 UpdateManager& Core::GetUpdateManager()
426 {
427   return *(mUpdateManager);
428 }
429
430 RenderManager& Core::GetRenderManager()
431 {
432   return *(mRenderManager);
433 }
434
435 NotificationManager& Core::GetNotificationManager()
436 {
437   return *(mNotificationManager);
438 }
439
440 ResourceManager& Core::GetResourceManager()
441 {
442   return *(mResourceManager);
443 }
444
445 ResourceClient& Core::GetResourceClient()
446 {
447   return *(mResourceClient);
448 }
449
450 ImageFactory& Core::GetImageFactory()
451 {
452   return *(mImageFactory);
453 }
454
455 ShaderFactory& Core::GetShaderFactory()
456 {
457   return *(mShaderFactory);
458 }
459
460 GestureEventProcessor& Core::GetGestureEventProcessor()
461 {
462   return *(mGestureEventProcessor);
463 }
464
465 RelayoutController& Core::GetRelayoutController()
466 {
467   return *(mRelayoutController.Get());
468 }
469
470 void Core::CreateThreadLocalStorage()
471 {
472   // a pointer to the ThreadLocalStorage object will be stored in TLS
473   // and automatically deleted when the thread is killed
474   new ThreadLocalStorage(this);
475 }
476
477 } // namespace Internal
478
479 } // namespace Dali