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