Ensure the processor unregistered during the callback is not executed
[platform/core/uifw/dali-core.git] / dali / internal / common / core-impl.cpp
1 /*
2  * Copyright (c) 2022 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/graphics-api/graphics-controller.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-context-helper-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/event-thread-services.h>
34 #include <dali/internal/event/common/notification-manager.h>
35 #include <dali/internal/event/common/property-notification-manager.h>
36 #include <dali/internal/event/common/stage-impl.h>
37 #include <dali/internal/event/common/thread-local-storage.h>
38 #include <dali/internal/event/common/type-registry-impl.h>
39 #include <dali/internal/event/effects/shader-factory.h>
40 #include <dali/internal/event/events/event-processor.h>
41 #include <dali/internal/event/events/gesture-event-processor.h>
42 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
43 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
44
45 #include <dali/internal/update/common/discard-queue.h>
46 #include <dali/internal/update/manager/render-task-processor.h>
47 #include <dali/internal/update/manager/update-manager.h>
48
49 #include <dali/internal/render/common/performance-monitor.h>
50 #include <dali/internal/render/common/render-manager.h>
51
52 using Dali::Internal::SceneGraph::DiscardQueue;
53 using Dali::Internal::SceneGraph::RenderManager;
54 using Dali::Internal::SceneGraph::RenderQueue;
55 using Dali::Internal::SceneGraph::UpdateManager;
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 } // namespace
66
67 namespace Dali
68 {
69 namespace Internal
70 {
71 using Integration::Event;
72 using Integration::GlAbstraction;
73 using Integration::GlContextHelperAbstraction;
74 using Integration::PlatformAbstraction;
75 using Integration::RenderController;
76 using Integration::RenderStatus;
77 using Integration::UpdateStatus;
78
79 Core::Core(RenderController&                   renderController,
80            PlatformAbstraction&                platform,
81            Graphics::Controller&               graphicsController,
82            Integration::RenderToFrameBuffer    renderToFboEnabled,
83            Integration::DepthBufferAvailable   depthBufferAvailable,
84            Integration::StencilBufferAvailable stencilBufferAvailable,
85            Integration::PartialUpdateAvailable partialUpdateAvailable)
86 : mRenderController(renderController),
87   mPlatform(platform),
88   mGraphicsController(graphicsController),
89   mProcessingEvent(false),
90   mForceNextUpdate(false),
91   mProcessorUnregistered(false),
92   mPostProcessorUnregistered(false)
93 {
94   // Create the thread local storage
95   CreateThreadLocalStorage();
96
97   // This does nothing until Core is built with --enable-performance-monitor
98   PERFORMANCE_MONITOR_INIT(platform);
99
100   mNotificationManager = new NotificationManager();
101
102   mAnimationPlaylist = AnimationPlaylist::New();
103
104   mPropertyNotificationManager = PropertyNotificationManager::New();
105
106   mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor();
107
108   mRenderManager = RenderManager::New(graphicsController, depthBufferAvailable, stencilBufferAvailable, partialUpdateAvailable);
109
110   RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
111
112   mDiscardQueue = new DiscardQueue(renderQueue);
113
114   mUpdateManager = new UpdateManager(*mNotificationManager,
115                                      *mAnimationPlaylist,
116                                      *mPropertyNotificationManager,
117                                      *mDiscardQueue,
118                                      renderController,
119                                      *mRenderManager,
120                                      renderQueue,
121                                      *mRenderTaskProcessor);
122
123   mRenderManager->SetShaderSaver(*mUpdateManager);
124
125   mObjectRegistry = ObjectRegistry::New();
126
127   mStage = IntrusivePtr<Stage>(Stage::New(*mUpdateManager));
128
129   // This must be called after stage is created but before stage initialization
130   mRelayoutController = IntrusivePtr<RelayoutController>(new RelayoutController(mRenderController));
131
132   mGestureEventProcessor = new GestureEventProcessor(*mUpdateManager, mRenderController);
133
134   mShaderFactory = new ShaderFactory();
135   mUpdateManager->SetShaderSaver(*mShaderFactory);
136
137   GetImplementation(Dali::TypeRegistry::Get()).CallInitFunctions();
138 }
139
140 Core::~Core()
141 {
142   /*
143    * The order of destructing these singletons is important!!!
144    */
145
146   // clear the thread local storage first
147   // allows core to be created / deleted many times in the same thread (how TET cases work).
148   // Do this before mStage.Reset() so Stage::IsInstalled() returns false
149   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
150   if(tls)
151   {
152     tls->Remove();
153     tls->Unreference();
154   }
155
156   mObjectRegistry.Reset();
157
158   // Stop relayout requests being raised on stage destruction
159   mRelayoutController.Reset();
160
161   // remove (last?) reference to stage
162   mStage.Reset();
163 }
164
165 void Core::Initialize()
166 {
167   mStage->Initialize(*mScenes[0]);
168 }
169
170 Integration::ContextNotifierInterface* Core::GetContextNotifier()
171 {
172   return mStage.Get();
173 }
174
175 void Core::RecoverFromContextLoss()
176 {
177   DALI_LOG_INFO(gCoreFilter, Debug::Verbose, "Core::RecoverFromContextLoss()\n");
178
179   mStage->GetRenderTaskList().RecoverFromContextLoss(); // Re-trigger render-tasks
180 }
181
182 void Core::ContextCreated()
183 {
184 }
185
186 void Core::ContextDestroyed()
187 {
188 }
189
190 void Core::Update(float elapsedSeconds, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds, Integration::UpdateStatus& status, bool renderToFboEnabled, bool isRenderingToFbo, bool uploadOnly)
191 {
192   // set the time delta so adaptor can easily print FPS with a release build with 0 as
193   // it is cached by frametime
194   status.secondsFromLastFrame = elapsedSeconds;
195
196   // Render returns true when there are updates on the stage or one or more animations are completed.
197   // Use the estimated time diff till we render as the elapsed time.
198   status.keepUpdating = mUpdateManager->Update(elapsedSeconds,
199                                                lastVSyncTimeMilliseconds,
200                                                nextVSyncTimeMilliseconds,
201                                                renderToFboEnabled,
202                                                isRenderingToFbo,
203                                                uploadOnly);
204
205   // Check the Notification Manager message queue to set needsNotification
206   status.needsNotification = mNotificationManager->MessagesToProcess();
207
208   // No need to keep update running if there are notifications to process.
209   // Any message to update will wake it up anyways
210 }
211
212 void Core::PreRender(RenderStatus& status, bool forceClear)
213 {
214   mRenderManager->PreRender(status, forceClear);
215 }
216
217 void Core::PreRender(Integration::Scene& scene, std::vector<Rect<int>>& damagedRects)
218 {
219   mRenderManager->PreRender(scene, damagedRects);
220 }
221
222 void Core::RenderScene(RenderStatus& status, Integration::Scene& scene, bool renderToFbo)
223 {
224   mRenderManager->RenderScene(status, scene, renderToFbo);
225 }
226
227 void Core::RenderScene(RenderStatus& status, Integration::Scene& scene, bool renderToFbo, Rect<int>& clippingRect)
228 {
229   mRenderManager->RenderScene(status, scene, renderToFbo, clippingRect);
230 }
231
232 void Core::PostRender()
233 {
234   mRenderManager->PostRender();
235 }
236
237 void Core::SceneCreated()
238 {
239   mStage->EmitSceneCreatedSignal();
240
241   mRelayoutController->OnApplicationSceneCreated();
242
243   for(const auto& scene : mScenes)
244   {
245     Dali::Actor sceneRootLayer = scene->GetRootLayer();
246     mRelayoutController->RequestRelayoutTree(sceneRootLayer);
247   }
248 }
249
250 void Core::QueueEvent(const Integration::Event& event)
251 {
252   if(mScenes.size() != 0)
253   {
254     mScenes.front()->QueueEvent(event);
255   }
256 }
257
258 void Core::ProcessEvents()
259 {
260   // Guard against calls to ProcessEvents() during ProcessEvents()
261   if(mProcessingEvent)
262   {
263     DALI_LOG_ERROR("ProcessEvents should not be called from within ProcessEvents!\n");
264     mRenderController.RequestProcessEventsOnIdle(false);
265     return;
266   }
267
268   mProcessingEvent = true;
269   mRelayoutController->SetProcessingCoreEvents(true);
270
271   // Signal that any messages received will be flushed soon
272   mUpdateManager->EventProcessingStarted();
273
274   // Scene could be added or removed while processing the events
275   // Copy the Scene container locally to avoid possibly invalid iterator
276   SceneContainer scenes = mScenes;
277
278   // process events in all scenes
279   for(auto scene : scenes)
280   {
281     scene->ProcessEvents();
282   }
283
284   mNotificationManager->ProcessMessages();
285
286   // Emit signal here to inform listeners that event processing has finished.
287   for(auto scene : scenes)
288   {
289     scene->EmitEventProcessingFinishedSignal();
290   }
291
292   // Run any registered processors
293   RunProcessors();
294
295   // Run the size negotiation after event processing finished signal
296   mRelayoutController->Relayout();
297
298   // Run any registered post processors
299   RunPostProcessors();
300
301   // Rebuild depth tree after event processing has finished
302   for(auto scene : scenes)
303   {
304     scene->RebuildDepthTree();
305   }
306
307   // Flush any queued messages for the update-thread
308   const bool messagesToProcess = mUpdateManager->FlushQueue();
309
310   // Check if the touch or gestures require updates.
311   const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
312   // Check if the next update is forced.
313   const bool forceUpdate = IsNextUpdateForced();
314
315   if(messagesToProcess || gestureNeedsUpdate || forceUpdate)
316   {
317     // tell the render controller to keep update thread running
318     mRenderController.RequestUpdate(forceUpdate);
319   }
320
321   mRelayoutController->SetProcessingCoreEvents(false);
322
323   // ProcessEvents() may now be called again
324   mProcessingEvent = false;
325 }
326
327 uint32_t Core::GetMaximumUpdateCount() const
328 {
329   return MAXIMUM_UPDATE_COUNT;
330 }
331
332 void Core::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
333 {
334   if(postProcessor)
335   {
336     mPostProcessors.PushBack(&processor);
337   }
338   else
339   {
340     mProcessors.PushBack(&processor);
341   }
342 }
343
344 void Core::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
345 {
346   if(postProcessor)
347   {
348     auto iter = std::find(mPostProcessors.Begin(), mPostProcessors.End(), &processor);
349     if(iter != mPostProcessors.End())
350     {
351       mPostProcessors.Erase(iter);
352       mPostProcessorUnregistered = true;
353     }
354   }
355   else
356   {
357     auto iter = std::find(mProcessors.Begin(), mProcessors.End(), &processor);
358     if(iter != mProcessors.End())
359     {
360       mProcessors.Erase(iter);
361       mProcessorUnregistered = true;
362     }
363   }
364 }
365
366 void Core::RunProcessors()
367 {
368   // Copy processor pointers to prevent changes to vector affecting loop iterator.
369   Dali::Vector<Integration::Processor*> processors(mProcessors);
370
371   // To prevent accessing processor unregistered during the loop
372   mProcessorUnregistered = false;
373
374   for(auto processor : processors)
375   {
376     if(processor)
377     {
378       if(!mProcessorUnregistered)
379       {
380         processor->Process(false);
381       }
382       else
383       {
384         // Run processor if the processor is still in the list.
385         // It may be removed during the loop.
386         auto iter = std::find(mProcessors.Begin(), mProcessors.End(), processor);
387         if(iter != mProcessors.End())
388         {
389           processor->Process(false);
390         }
391       }
392     }
393   }
394 }
395
396 void Core::RunPostProcessors()
397 {
398   // Copy processor pointers to prevent changes to vector affecting loop iterator.
399   Dali::Vector<Integration::Processor*> processors(mPostProcessors);
400
401   // To prevent accessing processor unregistered during the loop
402   mPostProcessorUnregistered = false;
403
404   for(auto processor : processors)
405   {
406     if(processor)
407     {
408       if(!mPostProcessorUnregistered)
409       {
410         processor->Process(true);
411       }
412       else
413       {
414         // Run processor if the processor is still in the list.
415         // It may be removed during the loop.
416         auto iter = std::find(mPostProcessors.Begin(), mPostProcessors.End(), processor);
417         if(iter != mPostProcessors.End())
418         {
419           processor->Process(true);
420         }
421       }
422     }
423   }
424 }
425
426 StagePtr Core::GetCurrentStage()
427 {
428   return mStage.Get();
429 }
430
431 PlatformAbstraction& Core::GetPlatform()
432 {
433   return mPlatform;
434 }
435
436 UpdateManager& Core::GetUpdateManager()
437 {
438   return *(mUpdateManager);
439 }
440
441 RenderManager& Core::GetRenderManager()
442 {
443   return *(mRenderManager);
444 }
445
446 NotificationManager& Core::GetNotificationManager()
447 {
448   return *(mNotificationManager);
449 }
450
451 ShaderFactory& Core::GetShaderFactory()
452 {
453   return *(mShaderFactory);
454 }
455
456 GestureEventProcessor& Core::GetGestureEventProcessor()
457 {
458   return *(mGestureEventProcessor);
459 }
460
461 RelayoutController& Core::GetRelayoutController()
462 {
463   return *(mRelayoutController.Get());
464 }
465
466 ObjectRegistry& Core::GetObjectRegistry() const
467 {
468   return *(mObjectRegistry.Get());
469 }
470
471 EventThreadServices& Core::GetEventThreadServices()
472 {
473   return *this;
474 }
475
476 PropertyNotificationManager& Core::GetPropertyNotificationManager() const
477 {
478   return *(mPropertyNotificationManager);
479 }
480
481 AnimationPlaylist& Core::GetAnimationPlaylist() const
482 {
483   return *(mAnimationPlaylist);
484 }
485
486 Integration::GlAbstraction& Core::GetGlAbstraction() const
487 {
488   return mGraphicsController.GetGlAbstraction();
489 }
490
491 void Core::AddScene(Scene* scene)
492 {
493   mScenes.push_back(scene);
494 }
495
496 void Core::RemoveScene(Scene* scene)
497 {
498   auto iter = std::find(mScenes.begin(), mScenes.end(), scene);
499   if(iter != mScenes.end())
500   {
501     mScenes.erase(iter);
502   }
503 }
504
505 void Core::CreateThreadLocalStorage()
506 {
507   // a pointer to the ThreadLocalStorage object will be stored in TLS
508   // The ThreadLocalStorage object should be deleted by the Core destructor
509   ThreadLocalStorage* tls = new ThreadLocalStorage(this);
510   tls->Reference();
511 }
512
513 void Core::RegisterObject(Dali::BaseObject* object)
514 {
515   mObjectRegistry = &ThreadLocalStorage::Get().GetObjectRegistry();
516   mObjectRegistry->RegisterObject(object);
517 }
518
519 void Core::UnregisterObject(Dali::BaseObject* object)
520 {
521   mObjectRegistry = &ThreadLocalStorage::Get().GetObjectRegistry();
522   mObjectRegistry->UnregisterObject(object);
523 }
524
525 Integration::RenderController& Core::GetRenderController()
526 {
527   return mRenderController;
528 }
529
530 uint32_t* Core::ReserveMessageSlot(uint32_t size, bool updateScene)
531 {
532   return mUpdateManager->ReserveMessageSlot(size, updateScene);
533 }
534
535 BufferIndex Core::GetEventBufferIndex() const
536 {
537   return mUpdateManager->GetEventBufferIndex();
538 }
539
540 void Core::ForceNextUpdate()
541 {
542   mForceNextUpdate = true;
543 }
544
545 bool Core::IsNextUpdateForced()
546 {
547   bool nextUpdateForced = mForceNextUpdate;
548   mForceNextUpdate      = false;
549   return nextUpdateForced;
550 }
551
552 } // namespace Internal
553
554 } // namespace Dali