[Tizen] Add some logs to check performance
[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   if(mProcessors.Count() != 0)
369   {
370     DALI_LOG_RELEASE_INFO("Start RunProcessors\n");
371
372     // Copy processor pointers to prevent changes to vector affecting loop iterator.
373     Dali::Vector<Integration::Processor*> processors(mProcessors);
374
375     // To prevent accessing processor unregistered during the loop
376     mProcessorUnregistered = false;
377
378     for(auto processor : processors)
379     {
380       if(processor)
381       {
382         if(!mProcessorUnregistered)
383         {
384           processor->Process(false);
385         }
386         else
387         {
388           // Run processor if the processor is still in the list.
389           // It may be removed during the loop.
390           auto iter = std::find(mProcessors.Begin(), mProcessors.End(), processor);
391           if(iter != mProcessors.End())
392           {
393             processor->Process(false);
394           }
395         }
396       }
397     }
398     DALI_LOG_RELEASE_INFO("End RunProcessors\n");
399   }
400 }
401
402 void Core::RunPostProcessors()
403 {
404   if(mPostProcessors.Count() != 0)
405   {
406     DALI_LOG_RELEASE_INFO("Start RunPostProcessors\n");
407
408     // Copy processor pointers to prevent changes to vector affecting loop iterator.
409     Dali::Vector<Integration::Processor*> processors(mPostProcessors);
410
411     // To prevent accessing processor unregistered during the loop
412     mPostProcessorUnregistered = false;
413
414     for(auto processor : processors)
415     {
416       if(processor)
417       {
418         if(!mPostProcessorUnregistered)
419         {
420           processor->Process(true);
421         }
422         else
423         {
424           // Run processor if the processor is still in the list.
425           // It may be removed during the loop.
426           auto iter = std::find(mPostProcessors.Begin(), mPostProcessors.End(), processor);
427           if(iter != mPostProcessors.End())
428           {
429             processor->Process(true);
430           }
431         }
432       }
433     }
434     DALI_LOG_RELEASE_INFO("End RunPostProcessors\n");
435   }
436 }
437
438 StagePtr Core::GetCurrentStage()
439 {
440   return mStage.Get();
441 }
442
443 PlatformAbstraction& Core::GetPlatform()
444 {
445   return mPlatform;
446 }
447
448 UpdateManager& Core::GetUpdateManager()
449 {
450   return *(mUpdateManager);
451 }
452
453 RenderManager& Core::GetRenderManager()
454 {
455   return *(mRenderManager);
456 }
457
458 NotificationManager& Core::GetNotificationManager()
459 {
460   return *(mNotificationManager);
461 }
462
463 ShaderFactory& Core::GetShaderFactory()
464 {
465   return *(mShaderFactory);
466 }
467
468 GestureEventProcessor& Core::GetGestureEventProcessor()
469 {
470   return *(mGestureEventProcessor);
471 }
472
473 RelayoutController& Core::GetRelayoutController()
474 {
475   return *(mRelayoutController.Get());
476 }
477
478 ObjectRegistry& Core::GetObjectRegistry() const
479 {
480   return *(mObjectRegistry.Get());
481 }
482
483 EventThreadServices& Core::GetEventThreadServices()
484 {
485   return *this;
486 }
487
488 PropertyNotificationManager& Core::GetPropertyNotificationManager() const
489 {
490   return *(mPropertyNotificationManager);
491 }
492
493 AnimationPlaylist& Core::GetAnimationPlaylist() const
494 {
495   return *(mAnimationPlaylist);
496 }
497
498 Integration::GlAbstraction& Core::GetGlAbstraction() const
499 {
500   return mGraphicsController.GetGlAbstraction();
501 }
502
503 void Core::AddScene(Scene* scene)
504 {
505   mScenes.push_back(scene);
506 }
507
508 void Core::RemoveScene(Scene* scene)
509 {
510   auto iter = std::find(mScenes.begin(), mScenes.end(), scene);
511   if(iter != mScenes.end())
512   {
513     mScenes.erase(iter);
514   }
515 }
516
517 void Core::CreateThreadLocalStorage()
518 {
519   // a pointer to the ThreadLocalStorage object will be stored in TLS
520   // The ThreadLocalStorage object should be deleted by the Core destructor
521   ThreadLocalStorage* tls = new ThreadLocalStorage(this);
522   tls->Reference();
523 }
524
525 void Core::RegisterObject(Dali::BaseObject* object)
526 {
527   mObjectRegistry = &ThreadLocalStorage::Get().GetObjectRegistry();
528   mObjectRegistry->RegisterObject(object);
529 }
530
531 void Core::UnregisterObject(Dali::BaseObject* object)
532 {
533   mObjectRegistry = &ThreadLocalStorage::Get().GetObjectRegistry();
534   mObjectRegistry->UnregisterObject(object);
535 }
536
537 Integration::RenderController& Core::GetRenderController()
538 {
539   return mRenderController;
540 }
541
542 uint32_t* Core::ReserveMessageSlot(uint32_t size, bool updateScene)
543 {
544   return mUpdateManager->ReserveMessageSlot(size, updateScene);
545 }
546
547 BufferIndex Core::GetEventBufferIndex() const
548 {
549   return mUpdateManager->GetEventBufferIndex();
550 }
551
552 void Core::ForceNextUpdate()
553 {
554   mForceNextUpdate = true;
555 }
556
557 bool Core::IsNextUpdateForced()
558 {
559   bool nextUpdateForced = mForceNextUpdate;
560   mForceNextUpdate      = false;
561   return nextUpdateForced;
562 }
563
564 } // namespace Internal
565
566 } // namespace Dali