Separating Processor Interface from core.h
[platform/core/uifw/dali-core.git] / dali / internal / common / core-impl.cpp
1 /*
2  * Copyright (c) 2019 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/processor-interface.h>
29 #include <dali/integration-api/render-controller.h>
30
31 #include <dali/internal/event/actors/actor-impl.h>
32 #include <dali/internal/event/animation/animation-playlist.h>
33 #include <dali/internal/event/common/notification-manager.h>
34 #include <dali/internal/event/common/property-notification-manager.h>
35 #include <dali/internal/event/common/stage-impl.h>
36 #include <dali/internal/event/common/thread-local-storage.h>
37 #include <dali/internal/event/common/type-registry-impl.h>
38 #include <dali/internal/event/effects/shader-factory.h>
39 #include <dali/internal/event/events/event-processor.h>
40 #include <dali/internal/event/events/gesture-event-processor.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/manager/update-manager.h>
46 #include <dali/internal/update/manager/render-task-processor.h>
47
48 #include <dali/internal/render/common/performance-monitor.h>
49 #include <dali/internal/render/common/render-manager.h>
50 #include <dali/internal/render/gl-resources/context.h>
51
52 using Dali::Internal::SceneGraph::UpdateManager;
53 using Dali::Internal::SceneGraph::RenderManager;
54 using Dali::Internal::SceneGraph::DiscardQueue;
55 using Dali::Internal::SceneGraph::RenderQueue;
56
57 namespace
58 {
59 // The Update for frame N+1 may be processed whilst frame N is being rendered.
60 const uint32_t MAXIMUM_UPDATE_COUNT = 2u;
61
62 #if defined(DEBUG_ENABLED)
63 Debug::Filter* gCoreFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CORE");
64 #endif
65 }
66
67 namespace Dali
68 {
69
70 namespace Internal
71 {
72
73 using Integration::RenderController;
74 using Integration::PlatformAbstraction;
75 using Integration::GlSyncAbstraction;
76 using Integration::GestureManager;
77 using Integration::GlAbstraction;
78 using Integration::Event;
79 using Integration::UpdateStatus;
80 using Integration::RenderStatus;
81
82 Core::Core( RenderController& renderController,
83             PlatformAbstraction& platform,
84             GlAbstraction& glAbstraction,
85             GlSyncAbstraction& glSyncAbstraction,
86             GestureManager& gestureManager,
87             ResourcePolicy::DataRetention dataRetentionPolicy,
88             Integration::RenderToFrameBuffer renderToFboEnabled,
89             Integration::DepthBufferAvailable depthBufferAvailable,
90             Integration::StencilBufferAvailable stencilBufferAvailable )
91 : mRenderController( renderController ),
92   mPlatform(platform),
93   mProcessingEvent(false)
94 {
95   // Create the thread local storage
96   CreateThreadLocalStorage();
97
98   // This does nothing until Core is built with --enable-performance-monitor
99   PERFORMANCE_MONITOR_INIT( platform );
100
101   mNotificationManager = new NotificationManager();
102
103   mAnimationPlaylist = AnimationPlaylist::New();
104
105   mPropertyNotificationManager = PropertyNotificationManager::New();
106
107   mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor();
108
109   mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, depthBufferAvailable, stencilBufferAvailable );
110
111   RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
112
113   mDiscardQueue = new DiscardQueue( renderQueue );
114
115   mUpdateManager = new UpdateManager( *mNotificationManager,
116                                       *mAnimationPlaylist,
117                                       *mPropertyNotificationManager,
118                                       *mDiscardQueue,
119                                        renderController,
120                                       *mRenderManager,
121                                        renderQueue,
122                                       *mRenderTaskProcessor );
123
124   mRenderManager->SetShaderSaver( *mUpdateManager );
125
126   mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager, mRenderController ) );
127
128   // This must be called after stage is created but before stage initialization
129   mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) );
130
131   mStage->Initialize( renderToFboEnabled == Integration::RenderToFrameBuffer::TRUE );
132
133   mGestureEventProcessor = new GestureEventProcessor( *mStage, *mUpdateManager, gestureManager, mRenderController );
134   mEventProcessor = new EventProcessor( *mStage, *mNotificationManager, *mGestureEventProcessor );
135
136   mShaderFactory = new ShaderFactory();
137   mUpdateManager->SetShaderSaver( *mShaderFactory );
138
139   GetImplementation(Dali::TypeRegistry::Get()).CallInitFunctions();
140 }
141
142 Core::~Core()
143 {
144   /*
145    * The order of destructing these singletons is important!!!
146    */
147
148   // clear the thread local storage first
149   // allows core to be created / deleted many times in the same thread (how TET cases work).
150   // Do this before mStage.Reset() so Stage::IsInstalled() returns false
151   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
152   if( tls )
153   {
154     tls->Remove();
155     delete tls;
156   }
157
158   // Stop relayout requests being raised on stage destruction
159   mRelayoutController.Reset();
160
161   // Clean-up stage - remove default camera and root layer
162   mStage->Uninitialize();
163
164   // remove (last?) reference to stage
165   mStage.Reset();
166
167 }
168
169 Integration::ContextNotifierInterface* Core::GetContextNotifier()
170 {
171   return mStage.Get();
172 }
173
174 void Core::RecoverFromContextLoss()
175 {
176   DALI_LOG_INFO(gCoreFilter, Debug::Verbose, "Core::RecoverFromContextLoss()\n");
177
178   mStage->GetRenderTaskList().RecoverFromContextLoss(); // Re-trigger render-tasks
179 }
180
181 void Core::ContextCreated()
182 {
183   mRenderManager->ContextCreated();
184 }
185
186 void Core::ContextDestroyed()
187 {
188   mRenderManager->ContextDestroyed();
189 }
190
191 void Core::SurfaceResized( uint32_t width, uint32_t height )
192 {
193   mStage->SurfaceResized( static_cast<float>( width ), static_cast<float>( height ) );
194
195   // The stage-size may be less than surface-size (reduced by top-margin)
196   Vector2 size = mStage->GetSize();
197   mRelayoutController->SetStageSize( static_cast<uint32_t>( size.width ), static_cast<uint32_t>( size.height ) ); // values get truncated
198 }
199
200 void Core::SetTopMargin( uint32_t margin )
201 {
202   mStage->SetTopMargin( margin );
203
204   // The stage-size may be less than surface-size (reduced by top-margin)
205   Vector2 size = mStage->GetSize();
206   mRelayoutController->SetStageSize( static_cast<uint32_t>( size.width ), static_cast<uint32_t>( size.height ) ); // values get truncated
207 }
208
209 void Core::SetDpi( uint32_t dpiHorizontal, uint32_t dpiVertical )
210 {
211   mStage->SetDpi( Vector2( static_cast<float>( dpiHorizontal ), static_cast<float>( dpiVertical ) ) );
212 }
213
214 void Core::Update( float elapsedSeconds, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds, Integration::UpdateStatus& status, bool renderToFboEnabled, bool isRenderingToFbo )
215 {
216   // set the time delta so adaptor can easily print FPS with a release build with 0 as
217   // it is cached by frametime
218   status.secondsFromLastFrame = elapsedSeconds;
219
220   // Render returns true when there are updates on the stage or one or more animations are completed.
221   // Use the estimated time diff till we render as the elapsed time.
222   status.keepUpdating = mUpdateManager->Update( elapsedSeconds,
223                                                 lastVSyncTimeMilliseconds,
224                                                 nextVSyncTimeMilliseconds,
225                                                 renderToFboEnabled,
226                                                 isRenderingToFbo );
227
228   // Check the Notification Manager message queue to set needsNotification
229   status.needsNotification = mNotificationManager->MessagesToProcess();
230
231   // Check if the default surface is changed
232   status.surfaceRectChanged = mUpdateManager->IsDefaultSurfaceRectChanged();
233
234   // No need to keep update running if there are notifications to process.
235   // Any message to update will wake it up anyways
236 }
237
238 void Core::Render( RenderStatus& status, bool forceClear )
239 {
240   mRenderManager->Render( status, forceClear );
241 }
242
243 void Core::SceneCreated()
244 {
245   mStage->EmitSceneCreatedSignal();
246
247   mRelayoutController->OnApplicationSceneCreated();
248 }
249
250 void Core::QueueEvent( const Integration::Event& event )
251 {
252   mEventProcessor->QueueEvent( event );
253 }
254
255 void Core::ProcessEvents()
256 {
257   // Guard against calls to ProcessEvents() during ProcessEvents()
258   if( mProcessingEvent )
259   {
260     DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!\n" );
261     mRenderController.RequestProcessEventsOnIdle( false );
262     return;
263   }
264
265   mProcessingEvent = true;
266   mRelayoutController->SetProcessingCoreEvents( true );
267
268   // Signal that any messages received will be flushed soon
269   mUpdateManager->EventProcessingStarted();
270
271   mEventProcessor->ProcessEvents();
272
273   mNotificationManager->ProcessMessages();
274
275   // Emit signal here to inform listeners that event processing has finished.
276   mStage->EmitEventProcessingFinishedSignal();
277
278   // Run any registered processors
279   RunProcessors();
280
281   // Run the size negotiation after event processing finished signal
282   mRelayoutController->Relayout();
283
284
285   // Rebuild depth tree after event processing has finished
286   mStage->RebuildDepthTree();
287
288   // Flush any queued messages for the update-thread
289   const bool messagesToProcess = mUpdateManager->FlushQueue();
290
291   // Check if the touch or gestures require updates.
292   const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
293   // Check if the next update is forced.
294   const bool forceUpdate = mStage->IsNextUpdateForced();
295
296   if( messagesToProcess || gestureNeedsUpdate || forceUpdate )
297   {
298     // tell the render controller to keep update thread running
299     mRenderController.RequestUpdate( forceUpdate );
300   }
301
302   mRelayoutController->SetProcessingCoreEvents( false );
303
304   // ProcessEvents() may now be called again
305   mProcessingEvent = false;
306 }
307
308 uint32_t Core::GetMaximumUpdateCount() const
309 {
310   return MAXIMUM_UPDATE_COUNT;
311 }
312
313 Integration::SystemOverlay& Core::GetSystemOverlay()
314 {
315   return mStage->GetSystemOverlay();
316 }
317
318 void Core::RegisterProcessor( Integration::Processor& processor )
319 {
320   mProcessors.PushBack(&processor);
321 }
322
323 void Core::UnregisterProcessor( Integration::Processor& processor )
324 {
325   auto iter = std::find( mProcessors.Begin(), mProcessors.End(), &processor );
326   if( iter != mProcessors.End() )
327   {
328     mProcessors.Erase( iter );
329   }
330 }
331
332 void Core::RunProcessors()
333 {
334   // Copy processor pointers to prevent changes to vector affecting loop iterator.
335   Dali::Vector<Integration::Processor*> processors( mProcessors );
336
337   for( auto processor : processors )
338   {
339     if( processor )
340     {
341       processor->Process();
342     }
343   }
344 }
345
346 StagePtr Core::GetCurrentStage()
347 {
348   return mStage.Get();
349 }
350
351 PlatformAbstraction& Core::GetPlatform()
352 {
353   return mPlatform;
354 }
355
356 UpdateManager& Core::GetUpdateManager()
357 {
358   return *(mUpdateManager);
359 }
360
361 RenderManager& Core::GetRenderManager()
362 {
363   return *(mRenderManager);
364 }
365
366 NotificationManager& Core::GetNotificationManager()
367 {
368   return *(mNotificationManager);
369 }
370
371 ShaderFactory& Core::GetShaderFactory()
372 {
373   return *(mShaderFactory);
374 }
375
376 GestureEventProcessor& Core::GetGestureEventProcessor()
377 {
378   return *(mGestureEventProcessor);
379 }
380
381 RelayoutController& Core::GetRelayoutController()
382 {
383   return *(mRelayoutController.Get());
384 }
385
386 void Core::CreateThreadLocalStorage()
387 {
388   // a pointer to the ThreadLocalStorage object will be stored in TLS
389   // The ThreadLocalStorage object should be deleted by the Core destructor
390   new ThreadLocalStorage(this);
391 }
392
393 } // namespace Internal
394
395 } // namespace Dali