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