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