Memory Pool Logging
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-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/adaptor/common/adaptor-builder-impl.h>
20 #include <dali/internal/adaptor/common/adaptor-impl.h>
21 #include <dali/internal/addons/common/addon-manager-factory.h>
22 #include <dali/internal/addons/common/addon-manager-impl.h>
23
24 // EXTERNAL INCLUDES
25 #include <dali/devel-api/actors/actor-devel.h>
26 #include <dali/devel-api/common/stage.h>
27 #include <dali/integration-api/addon-manager.h>
28 #include <dali/integration-api/context-notifier.h>
29 #include <dali/integration-api/core.h>
30 #include <dali/integration-api/debug.h>
31 #include <dali/integration-api/events/key-event-integ.h>
32 #include <dali/integration-api/events/touch-event-integ.h>
33 #include <dali/integration-api/events/wheel-event-integ.h>
34 #include <dali/integration-api/input-options.h>
35 #include <dali/integration-api/processor-interface.h>
36 #include <dali/integration-api/profiling.h>
37 #include <dali/integration-api/trace.h>
38 #include <dali/public-api/actors/layer.h>
39 #include <dali/public-api/events/wheel-event.h>
40 #include <dali/public-api/object/any.h>
41 #include <dali/public-api/object/object-registry.h>
42 #include <errno.h>
43 #include <sys/stat.h>
44
45 // INTERNAL INCLUDES
46 #include <dali/internal/adaptor/common/lifecycle-observer.h>
47 #include <dali/internal/adaptor/common/thread-controller-interface.h>
48 #include <dali/internal/system/common/performance-interface-factory.h>
49 #include <dali/internal/system/common/thread-controller.h>
50 #include <dali/public-api/dali-adaptor-common.h>
51
52 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
53 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
54
55 #include <dali/devel-api/text-abstraction/font-client.h>
56
57 #include <dali/internal/accessibility/common/tts-player-impl.h>
58 #include <dali/internal/clipboard/common/clipboard-impl.h>
59 #include <dali/internal/graphics/common/egl-image-extensions.h>
60 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
61 #include <dali/internal/graphics/gles/gl-implementation.h>
62 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
63 #include <dali/internal/system/common/callback-manager.h>
64 #include <dali/internal/system/common/object-profiler.h>
65 #include <dali/internal/window-system/common/display-connection.h>
66 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
67 #include <dali/internal/window-system/common/event-handler.h>
68 #include <dali/internal/window-system/common/window-impl.h>
69 #include <dali/internal/window-system/common/window-render-surface.h>
70
71 #include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
72 #include <dali/internal/system/common/logging.h>
73
74 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
75 #include <dali/internal/imaging/common/image-loader.h>
76 #include <dali/internal/system/common/locale-utils.h>
77
78 #include <dali/internal/system/common/configuration-manager.h>
79 #include <dali/internal/system/common/environment-variables.h>
80
81 using Dali::TextAbstraction::FontClient;
82
83 extern std::string GetSystemCachePath();
84
85 namespace Dali
86 {
87 namespace Internal
88 {
89 namespace Adaptor
90 {
91 namespace
92 {
93 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
94
95 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_PERFORMANCE_MARKER, false);
96 } // unnamed namespace
97
98 Dali::Adaptor* Adaptor::New(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
99 {
100   Dali::Adaptor* adaptor = new Dali::Adaptor;
101   Adaptor*       impl    = new Adaptor(window, *adaptor, surface, environmentOptions, threadMode);
102   adaptor->mImpl         = impl;
103
104   Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder(*(impl->mEnvironmentOptions));
105   auto                                     graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
106
107   impl->Initialize(graphicsFactory);
108   delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
109
110   return adaptor;
111 }
112
113 Dali::Adaptor* Adaptor::New(Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions)
114 {
115   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(window);
116   Dali::Adaptor*                  adaptor    = New(window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL);
117   windowImpl.SetAdaptor(*adaptor);
118   return adaptor;
119 }
120
121 Dali::Adaptor* Adaptor::New(GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
122 {
123   Dali::Adaptor* adaptor = new Dali::Adaptor;                                                      // Public adaptor
124   Adaptor*       impl    = new Adaptor(window, *adaptor, surface, environmentOptions, threadMode); // Impl adaptor
125   adaptor->mImpl         = impl;
126
127   impl->Initialize(graphicsFactory);
128
129   return adaptor;
130 } // Called second
131
132 Dali::Adaptor* Adaptor::New(GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions)
133 {
134   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(window);
135   Dali::Adaptor*                  adaptor    = New(graphicsFactory, window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL);
136   windowImpl.SetAdaptor(*adaptor);
137   return adaptor;
138 } // Called first
139
140 void Adaptor::Initialize(GraphicsFactory& graphicsFactory)
141 {
142   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
143   Dali::Integration::Log::LogFunction logFunction(Dali::TizenPlatform::LogMessage);
144   mEnvironmentOptions->SetLogFunction(logFunction);
145   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
146
147   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
148
149   std::string path;
150   GetDataStoragePath(path);
151   mPlatformAbstraction->SetDataStoragePath(path);
152
153   if(mEnvironmentOptions->PerformanceServerRequired())
154   {
155     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface(*this, *mEnvironmentOptions);
156   }
157
158   mEnvironmentOptions->CreateTraceManager(mPerformanceInterface);
159   mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
160
161   mCallbackManager = CallbackManager::New();
162
163   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
164
165   DALI_ASSERT_DEBUG(defaultWindow->GetSurface() && "Surface not initialized");
166
167   mGraphics = std::unique_ptr<GraphicsInterface>(&graphicsFactory.Create());
168
169   // Create the AddOnManager
170   mAddOnManager.reset(Dali::Internal::AddOnManagerFactory::CreateAddOnManager());
171
172   mCore = Integration::Core::New(*this,
173                                  *mPlatformAbstraction,
174                                  mGraphics->GetController(),
175                                  (0u != mEnvironmentOptions->GetRenderToFboInterval()) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
176                                  mGraphics->GetDepthBufferRequired(),
177                                  mGraphics->GetStencilBufferRequired(),
178                                  mGraphics->GetPartialUpdateRequired());
179
180   defaultWindow->SetAdaptor(Get());
181
182   Dali::Integration::SceneHolder defaultSceneHolder(defaultWindow);
183
184   mWindowCreatedSignal.Emit(defaultSceneHolder);
185
186   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
187   if(0u < timeInterval)
188   {
189     mObjectProfiler = new ObjectProfiler(mCore->GetObjectRegistry(), timeInterval);
190   }
191
192   const uint32_t poolTimeInterval = mEnvironmentOptions->GetMemoryPoolInterval();
193   if(0u < poolTimeInterval)
194   {
195     mMemoryPoolTimer = Dali::Timer::New(poolTimeInterval * 1000);
196     mMemoryPoolTimer.TickSignal().Connect(mMemoryPoolTimerSlotDelegate, &Adaptor::MemoryPoolTimeout);
197     mMemoryPoolTimer.Start();
198   }
199
200   mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &Adaptor::ProcessCoreEvents), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
201
202   mDisplayConnection = Dali::DisplayConnection::New(*mGraphics, defaultWindow->GetSurface()->GetSurfaceType());
203
204   mThreadController = new ThreadController(*this, *mEnvironmentOptions, mThreadMode);
205
206   // Should be called after Core creation
207   if(mEnvironmentOptions->GetPanGestureLoggingLevel())
208   {
209     Integration::EnableProfiling(Dali::Integration::PROFILING_TYPE_PAN_GESTURE);
210   }
211   if(mEnvironmentOptions->GetPanGesturePredictionMode() >= 0)
212   {
213     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
214   }
215   if(mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0)
216   {
217     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
218   }
219   if(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0)
220   {
221     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
222   }
223   if(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0)
224   {
225     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
226   }
227   if(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0)
228   {
229     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
230   }
231   if(mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0)
232   {
233     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
234   }
235   if(mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f)
236   {
237     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
238   }
239   if(mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0)
240   {
241     Integration::SetPanGestureUseActualTimes(mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false);
242   }
243   if(mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0)
244   {
245     Integration::SetPanGestureInterpolationTimeRange(mEnvironmentOptions->GetPanGestureInterpolationTimeRange());
246   }
247   if(mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0)
248   {
249     Integration::SetPanGestureScalarOnlyPredictionEnabled(mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false);
250   }
251   if(mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0)
252   {
253     Integration::SetPanGestureTwoPointPredictionEnabled(mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false);
254   }
255   if(mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0)
256   {
257     Integration::SetPanGestureTwoPointInterpolatePastTime(mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime());
258   }
259   if(mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f)
260   {
261     Integration::SetPanGestureTwoPointVelocityBias(mEnvironmentOptions->GetPanGestureTwoPointVelocityBias());
262   }
263   if(mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f)
264   {
265     Integration::SetPanGestureTwoPointAccelerationBias(mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias());
266   }
267   if(mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0)
268   {
269     Integration::SetPanGestureMultitapSmoothingRange(mEnvironmentOptions->GetPanGestureMultitapSmoothingRange());
270   }
271   if(mEnvironmentOptions->GetMinimumPanDistance() >= 0)
272   {
273     Integration::SetPanGestureMinimumDistance(mEnvironmentOptions->GetMinimumPanDistance());
274   }
275   if(mEnvironmentOptions->GetMinimumPanEvents() >= 0)
276   {
277     Integration::SetPanGestureMinimumPanEvents(mEnvironmentOptions->GetMinimumPanEvents());
278   }
279   if(mEnvironmentOptions->GetMinimumPinchDistance() >= 0)
280   {
281     Integration::SetPinchGestureMinimumDistance(mEnvironmentOptions->GetMinimumPinchDistance());
282   }
283   if(mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0)
284   {
285     Integration::SetPinchGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumPinchTouchEvents());
286   }
287   if(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0)
288   {
289     Integration::SetPinchGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart());
290   }
291   if(mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0)
292   {
293     Integration::SetRotationGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumRotationTouchEvents());
294   }
295   if(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0)
296   {
297     Integration::SetRotationGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart());
298   }
299   if(mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0)
300   {
301     Integration::SetLongPressMinimumHoldingTime(mEnvironmentOptions->GetLongPressMinimumHoldingTime());
302   }
303   if(mEnvironmentOptions->GetTapMaximumAllowedTime() > 0)
304   {
305     Integration::SetTapMaximumAllowedTime(mEnvironmentOptions->GetTapMaximumAllowedTime());
306   }
307
308   std::string systemCachePath = GetSystemCachePath();
309   if(!systemCachePath.empty())
310   {
311     const int dir_err = mkdir(systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
312     if(0 != dir_err && errno != EEXIST)
313     {
314       DALI_LOG_ERROR("Error creating system cache directory: %s!\n", systemCachePath.c_str());
315     }
316   }
317
318   mConfigurationManager = Utils::MakeUnique<ConfigurationManager>(systemCachePath, mGraphics.get(), mThreadController);
319 }
320
321 void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent(const Dali::KeyEvent& event)
322 {
323   Accessibility::KeyEventType type;
324   if(event.GetState() == Dali::KeyEvent::DOWN)
325   {
326     type = Accessibility::KeyEventType::KEY_PRESSED;
327   }
328   else if(event.GetState() == Dali::KeyEvent::UP)
329   {
330     type = Accessibility::KeyEventType::KEY_RELEASED;
331   }
332   else
333   {
334     return;
335   }
336   Dali::Accessibility::Bridge::GetCurrentBridge()->Emit(type, event.GetKeyCode(), event.GetKeyName(), event.GetTime(), !event.GetKeyString().empty());
337 }
338
339 Adaptor::~Adaptor()
340 {
341   Accessibility::Bridge::GetCurrentBridge()->Terminate();
342
343   // Ensure stop status
344   Stop();
345
346   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
347   gThreadLocalAdaptor = NULL;
348
349   for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
350   {
351     (*iter)->OnDestroy();
352   }
353
354   // Clear out all the handles to Windows
355   mWindows.clear();
356
357   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
358   delete mObjectProfiler;
359
360   delete mCore;
361
362   delete mDisplayConnection;
363   delete mPlatformAbstraction;
364   delete mCallbackManager;
365   delete mPerformanceInterface;
366
367   mGraphics->Destroy();
368
369   // uninstall it on this thread (main actor thread)
370   Dali::Integration::Log::UninstallLogFunction();
371
372   // Delete environment options if we own it
373   if(mEnvironmentOptionsOwned)
374   {
375     delete mEnvironmentOptions;
376   }
377 }
378
379 void Adaptor::Start()
380 {
381   // It doesn't support restart after stop at this moment to support restarting, need more testing
382   if(READY != mState)
383   {
384     return;
385   }
386
387   mCore->Initialize();
388
389   SetupSystemInformation();
390
391   // Start the callback manager
392   mCallbackManager->Start();
393
394   // Initialize accessibility bridge after callback manager is started to use Idler callback
395   auto appName = GetApplicationPackageName();
396   auto bridge  = Accessibility::Bridge::GetCurrentBridge();
397   bridge->SetApplicationName(appName);
398   bridge->Initialize();
399   Dali::Stage::GetCurrent().KeyEventSignal().Connect(&mAccessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent);
400
401   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
402
403   unsigned int dpiHor, dpiVer;
404   dpiHor = dpiVer = 0;
405
406   defaultWindow->GetSurface()->GetDpi(dpiHor, dpiVer);
407
408   // set the DPI value for font rendering
409   FontClient fontClient = FontClient::Get();
410   fontClient.SetDpi(dpiHor, dpiVer);
411
412   // Initialize the thread controller
413   mThreadController->Initialize();
414
415   // Set max texture size
416   if(mEnvironmentOptions->GetMaxTextureSize() > 0)
417   {
418     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(mEnvironmentOptions->GetMaxTextureSize());
419   }
420   else
421   {
422     unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
423     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(maxTextureSize);
424   }
425
426   // cache advanced blending and shader language version
427   mGraphics->CacheConfigurations(*mConfigurationManager.get());
428
429   ProcessCoreEvents(); // Ensure any startup messages are processed.
430
431   // Initialize the image loader plugin
432   Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
433
434   for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
435   {
436     (*iter)->OnStart();
437   }
438
439   if(mAddOnManager)
440   {
441     mAddOnManager->Start();
442   }
443 }
444
445 // Dali::Internal::Adaptor::Adaptor::Pause
446 void Adaptor::Pause()
447 {
448   // Only pause the adaptor if we're actually running.
449   if(RUNNING == mState)
450   {
451     // Inform observers that we are about to be paused.
452     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
453     {
454       (*iter)->OnPause();
455     }
456
457     // Extensions
458     if(mAddOnManager)
459     {
460       mAddOnManager->Pause();
461     }
462
463     // Pause all windows event handlers when adaptor paused
464     for(auto window : mWindows)
465     {
466       window->Pause();
467     }
468
469     mThreadController->Pause();
470     mState = PAUSED;
471
472     // Ensure any messages queued during pause callbacks are processed by doing another update.
473     RequestUpdateOnce();
474
475     DALI_LOG_RELEASE_INFO("Adaptor::Pause: Paused\n");
476   }
477   else
478   {
479     DALI_LOG_RELEASE_INFO("Adaptor::Pause: Not paused [%d]\n", mState);
480   }
481 }
482
483 // Dali::Internal::Adaptor::Adaptor::Resume
484 void Adaptor::Resume()
485 {
486   // Only resume the adaptor if we are in the suspended state.
487   if(PAUSED == mState)
488   {
489     mState = RUNNING;
490
491     // Reset the event handlers when adaptor resumed
492     for(auto window : mWindows)
493     {
494       window->Resume();
495     }
496
497     // Resume AddOnManager
498     if(mAddOnManager)
499     {
500       mAddOnManager->Resume();
501     }
502
503     // Inform observers that we have resumed.
504     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
505     {
506       (*iter)->OnResume();
507     }
508
509     // Trigger processing of events queued up while paused
510     mCore->ProcessEvents();
511
512     // Do at end to ensure our first update/render after resumption includes the processed messages as well
513     mThreadController->Resume();
514
515     DALI_LOG_RELEASE_INFO("Adaptor::Resume: Resumed\n");
516   }
517   else
518   {
519     DALI_LOG_RELEASE_INFO("Adaptor::Resume: Not resumed [%d]\n", mState);
520   }
521 }
522
523 void Adaptor::Stop()
524 {
525   if(RUNNING == mState ||
526      PAUSED == mState ||
527      PAUSED_WHILE_HIDDEN == mState)
528   {
529     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
530     {
531       (*iter)->OnStop();
532     }
533
534     if(mAddOnManager)
535     {
536       mAddOnManager->Stop();
537     }
538
539     mThreadController->Stop();
540
541     // Delete the TTS player
542     for(int i = 0; i < Dali::TtsPlayer::MODE_NUM; i++)
543     {
544       if(mTtsPlayers[i])
545       {
546         mTtsPlayers[i].Reset();
547       }
548     }
549
550     // Destroy the image loader plugin
551     Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
552
553     delete mNotificationTrigger;
554     mNotificationTrigger = NULL;
555
556     mCallbackManager->Stop();
557
558     mState = STOPPED;
559
560     DALI_LOG_RELEASE_INFO("Adaptor::Stop\n");
561   }
562 }
563
564 void Adaptor::ContextLost()
565 {
566   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
567 }
568
569 void Adaptor::ContextRegained()
570 {
571   // Inform core, so that texture resources can be reloaded
572   mCore->RecoverFromContextLoss();
573
574   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
575 }
576
577 void Adaptor::FeedTouchPoint(TouchPoint& point, int timeStamp)
578 {
579   Integration::Point convertedPoint(point);
580   mWindows.front()->FeedTouchPoint(convertedPoint, timeStamp);
581 }
582
583 void Adaptor::FeedWheelEvent(Dali::WheelEvent& wheelEvent)
584 {
585   Integration::WheelEvent event(static_cast<Integration::WheelEvent::Type>(wheelEvent.GetType()), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime());
586   mWindows.front()->FeedWheelEvent(event);
587 }
588
589 void Adaptor::FeedKeyEvent(Dali::KeyEvent& keyEvent)
590 {
591   Integration::KeyEvent convertedEvent(keyEvent.GetKeyName(), keyEvent.GetLogicalKey(), keyEvent.GetKeyString(), keyEvent.GetKeyCode(), keyEvent.GetKeyModifier(), keyEvent.GetTime(), static_cast<Integration::KeyEvent::State>(keyEvent.GetState()), keyEvent.GetCompose(), keyEvent.GetDeviceName(), keyEvent.GetDeviceClass(), keyEvent.GetDeviceSubclass());
592   mWindows.front()->FeedKeyEvent(convertedEvent);
593 }
594
595 void Adaptor::ReplaceSurface(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface)
596 {
597   Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation(window);
598   for(auto windowPtr : mWindows)
599   {
600     if(windowPtr == windowImpl) // the window is not deleted
601     {
602       mResizedSignal.Emit(mAdaptor);
603
604       windowImpl->SetSurface(&newSurface);
605
606       // Flush the event queue to give the update-render thread chance
607       // to start processing messages for new camera setup etc as soon as possible
608       ProcessCoreEvents();
609
610       // This method blocks until the render thread has completed the replace.
611       mThreadController->ReplaceSurface(&newSurface);
612       break;
613     }
614   }
615 }
616
617 void Adaptor::DeleteSurface(Dali::RenderSurfaceInterface& surface)
618 {
619   // Flush the event queue to give the update-render thread chance
620   // to start processing messages for new camera setup etc as soon as possible
621   ProcessCoreEvents();
622
623   // This method blocks until the render thread has finished rendering the current surface.
624   mThreadController->DeleteSurface(&surface);
625 }
626
627 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
628 {
629   return *mWindows.front()->GetSurface();
630 }
631
632 void Adaptor::ReleaseSurfaceLock()
633 {
634   mWindows.front()->GetSurface()->ReleaseLock();
635 }
636
637 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
638 {
639   if(!mTtsPlayers[mode])
640   {
641     // Create the TTS player when it needed, because it can reduce launching time.
642     mTtsPlayers[mode] = TtsPlayer::New(mode);
643   }
644
645   return mTtsPlayers[mode];
646 }
647
648 bool Adaptor::AddIdle(CallbackBase* callback, bool hasReturnValue, bool forceAdd)
649 {
650   bool idleAdded(false);
651
652   // Only add an idle if the Adaptor is actually running
653   if(RUNNING == mState || READY == mState || forceAdd)
654   {
655     idleAdded = mCallbackManager->AddIdleCallback(callback, hasReturnValue);
656   }
657
658   return idleAdded;
659 }
660
661 void Adaptor::RemoveIdle(CallbackBase* callback)
662 {
663   mCallbackManager->RemoveIdleCallback(callback);
664 }
665
666 void Adaptor::ProcessIdle()
667 {
668   bool idleProcessed           = mCallbackManager->ProcessIdle();
669   mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
670 }
671
672 void Adaptor::SetPreRenderCallback(CallbackBase* callback)
673 {
674   mThreadController->SetPreRenderCallback(callback);
675 }
676
677 bool Adaptor::AddWindow(Dali::Integration::SceneHolder childWindow)
678 {
679   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(childWindow);
680   windowImpl.SetAdaptor(Get());
681
682   // ChildWindow is set to the layout direction of the default window.
683   windowImpl.GetRootLayer().SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
684
685   // Add the new Window to the container - the order is not important
686   {
687     Dali::Mutex::ScopedLock lock(mMutex);
688     mWindows.push_back(&windowImpl);
689   }
690
691   Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
692
693   mThreadController->AddSurface(surface);
694
695   mWindowCreatedSignal.Emit(childWindow);
696
697   return true;
698 }
699
700 bool Adaptor::RemoveWindow(Dali::Integration::SceneHolder* childWindow)
701 {
702   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(*childWindow);
703   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
704   {
705     if(*iter == &windowImpl)
706     {
707       Dali::Mutex::ScopedLock lock(mMutex);
708       mWindows.erase(iter);
709       return true;
710     }
711   }
712
713   return false;
714 }
715
716 bool Adaptor::RemoveWindow(std::string childWindowName)
717 {
718   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
719   {
720     if((*iter)->GetName() == childWindowName)
721     {
722       Dali::Mutex::ScopedLock lock(mMutex);
723       mWindows.erase(iter);
724       return true;
725     }
726   }
727
728   return false;
729 }
730
731 bool Adaptor::RemoveWindow(Internal::Adaptor::SceneHolder* childWindow)
732 {
733   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
734   {
735     if((*iter)->GetId() == childWindow->GetId())
736     {
737       Dali::Mutex::ScopedLock lock(mMutex);
738       mWindows.erase(iter);
739       return true;
740     }
741   }
742
743   return false;
744 }
745
746 Dali::Adaptor& Adaptor::Get()
747 {
748   DALI_ASSERT_ALWAYS(IsAvailable() && "Adaptor not instantiated");
749   return gThreadLocalAdaptor->mAdaptor;
750 }
751
752 bool Adaptor::IsAvailable()
753 {
754   return gThreadLocalAdaptor != NULL;
755 }
756
757 void Adaptor::SceneCreated()
758 {
759   mCore->SceneCreated();
760 }
761
762 Dali::Integration::Core& Adaptor::GetCore()
763 {
764   return *mCore;
765 }
766
767 void Adaptor::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender)
768 {
769   mThreadController->SetRenderRefreshRate(numberOfVSyncsPerRender);
770 }
771
772 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
773 {
774   DALI_ASSERT_DEBUG(mDisplayConnection && "Display connection not created");
775   return *mDisplayConnection;
776 }
777
778 GraphicsInterface& Adaptor::GetGraphicsInterface()
779 {
780   DALI_ASSERT_DEBUG(mGraphics && "Graphics interface not created");
781   return *(mGraphics.get());
782 }
783
784 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
785 {
786   return *mPlatformAbstraction;
787 }
788
789 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
790 {
791   return *mNotificationTrigger;
792 }
793
794 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
795 {
796   return mSocketFactory;
797 }
798
799 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
800 {
801   if(!mWindows.empty())
802   {
803     return mWindows.front()->GetSurface();
804   }
805
806   return nullptr;
807 }
808
809 TraceInterface& Adaptor::GetKernelTraceInterface()
810 {
811   return mKernelTracer;
812 }
813
814 TraceInterface& Adaptor::GetSystemTraceInterface()
815 {
816   return mSystemTracer;
817 }
818
819 PerformanceInterface* Adaptor::GetPerformanceInterface()
820 {
821   return mPerformanceInterface;
822 }
823
824 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
825 {
826   DALI_ASSERT_DEBUG(mPlatformAbstraction && "PlatformAbstraction not created");
827   return *mPlatformAbstraction;
828 }
829
830 void Adaptor::GetWindowContainerInterface(WindowContainer& windows)
831 {
832   Dali::Mutex::ScopedLock lock(mMutex);
833   windows = mWindows;
834 }
835
836 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
837 {
838   if(mTtsPlayers[mode])
839   {
840     mTtsPlayers[mode].Reset();
841   }
842 }
843
844 Any Adaptor::GetNativeWindowHandle()
845 {
846   return mWindows.front()->GetNativeHandle();
847 }
848
849 Any Adaptor::GetNativeWindowHandle(Dali::Actor actor)
850 {
851   Any nativeWindowHandle;
852
853   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
854
855   for(auto sceneHolder : mWindows)
856   {
857     if(scene == sceneHolder->GetScene())
858     {
859       nativeWindowHandle = sceneHolder->GetNativeHandle();
860       break;
861     }
862   }
863
864   return nativeWindowHandle;
865 }
866
867 Any Adaptor::GetGraphicsDisplay()
868 {
869   Any display;
870
871   if(mGraphics)
872   {
873     GraphicsInterface* graphics    = mGraphics.get(); // This interface is temporary until Core has been updated to match
874     auto               eglGraphics = static_cast<EglGraphics*>(graphics);
875
876     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
877     display                    = eglImpl.GetDisplay();
878   }
879
880   return display;
881 }
882
883 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
884 {
885   mUseRemoteSurface = useRemoteSurface;
886 }
887
888 void Adaptor::AddObserver(LifeCycleObserver& observer)
889 {
890   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
891
892   if(match == mObservers.end())
893   {
894     mObservers.push_back(&observer);
895   }
896 }
897
898 void Adaptor::RemoveObserver(LifeCycleObserver& observer)
899 {
900   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
901
902   if(match != mObservers.end())
903   {
904     mObservers.erase(match);
905   }
906 }
907
908 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
909 {
910   if(mCore)
911   {
912     mCore->QueueEvent(event);
913   }
914 }
915
916 void Adaptor::ProcessCoreEvents()
917 {
918   if(mCore)
919   {
920     if(mPerformanceInterface)
921     {
922       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_START);
923     }
924
925     DALI_TRACE_BEGIN(gTraceFilter, "DALI_PROCESS_CORE_EVENTS");
926
927     mCore->ProcessEvents();
928
929     DALI_TRACE_END(gTraceFilter, "DALI_PROCESS_CORE_EVENTS");
930
931     if(mPerformanceInterface)
932     {
933       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_END);
934     }
935   }
936 }
937
938 void Adaptor::RequestUpdate(bool forceUpdate)
939 {
940   switch(mState)
941   {
942     case RUNNING:
943     {
944       mThreadController->RequestUpdate();
945       break;
946     }
947     case PAUSED:
948     case PAUSED_WHILE_HIDDEN:
949     {
950       if(forceUpdate)
951       {
952         // Update (and resource upload) without rendering
953         mThreadController->RequestUpdateOnce(UpdateMode::SKIP_RENDER);
954       }
955       break;
956     }
957     default:
958     {
959       // Do nothing
960       break;
961     }
962   }
963 }
964
965 void Adaptor::RequestProcessEventsOnIdle(bool forceProcess)
966 {
967   // Only request a notification if the Adaptor is actually running
968   // and we haven't installed the idle notification
969   if((!mNotificationOnIdleInstalled) && (RUNNING == mState || READY == mState || forceProcess))
970   {
971     mNotificationOnIdleInstalled = AddIdleEnterer(MakeCallback(this, &Adaptor::ProcessCoreEventsFromIdle), forceProcess);
972   }
973 }
974
975 void Adaptor::OnWindowShown()
976 {
977   if(PAUSED_WHILE_HIDDEN == mState)
978   {
979     // Adaptor can now be resumed
980     mState = PAUSED;
981
982     Resume();
983
984     // Force a render task
985     RequestUpdateOnce();
986   }
987   else if(RUNNING == mState)
988   {
989     // Force a render task
990     RequestUpdateOnce();
991
992     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Update requested.\n");
993   }
994   else if(PAUSED_WHILE_INITIALIZING == mState)
995   {
996     // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
997     mState = READY;
998   }
999   else
1000   {
1001     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState);
1002   }
1003 }
1004
1005 void Adaptor::OnWindowHidden()
1006 {
1007   if(RUNNING == mState || READY == mState)
1008   {
1009     bool allWindowsHidden = true;
1010
1011     for(auto window : mWindows)
1012     {
1013       if(window->IsVisible())
1014       {
1015         allWindowsHidden = false;
1016         break;
1017       }
1018     }
1019
1020     // Only pause the adaptor when all the windows are hidden
1021     if(allWindowsHidden)
1022     {
1023       if(mState == RUNNING)
1024       {
1025         Pause();
1026
1027         // Adaptor cannot be resumed until any window is shown
1028         mState = PAUSED_WHILE_HIDDEN;
1029       }
1030       else // mState is READY
1031       {
1032         // Pause the adaptor after the state gets RUNNING
1033         mState = PAUSED_WHILE_INITIALIZING;
1034       }
1035     }
1036     else
1037     {
1038       DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n");
1039     }
1040   }
1041   else
1042   {
1043     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState);
1044   }
1045 }
1046
1047 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1048 void Adaptor::OnDamaged(const DamageArea& area)
1049 {
1050   // This is needed for the case where Dali window is partially obscured
1051   RequestUpdate(false);
1052 }
1053
1054 void Adaptor::SurfaceResizePrepare(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1055 {
1056   mResizedSignal.Emit(mAdaptor);
1057 }
1058
1059 void Adaptor::SurfaceResizeComplete(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1060 {
1061   // Nofify surface resizing before flushing event queue
1062   mThreadController->ResizeSurface();
1063
1064   // Flush the event queue to give the update-render thread chance
1065   // to start processing messages for new camera setup etc as soon as possible
1066   ProcessCoreEvents();
1067 }
1068
1069 void Adaptor::NotifySceneCreated()
1070 {
1071   GetCore().SceneCreated();
1072
1073   // Flush the event queue to give the update-render thread chance
1074   // to start processing messages for new camera setup etc as soon as possible
1075   ProcessCoreEvents();
1076
1077   // Start thread controller after the scene has been created
1078   mThreadController->Start();
1079
1080   // Process after surface is created (registering to remote surface provider if required)
1081   SurfaceInitialized();
1082
1083   if(mState != PAUSED_WHILE_INITIALIZING)
1084   {
1085     mState = RUNNING;
1086
1087     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is running\n");
1088   }
1089   else
1090   {
1091     mState = RUNNING;
1092
1093     Pause();
1094
1095     mState = PAUSED_WHILE_HIDDEN;
1096
1097     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is paused\n");
1098   }
1099 }
1100
1101 void Adaptor::NotifyLanguageChanged()
1102 {
1103   mLanguageChangedSignal.Emit(mAdaptor);
1104 }
1105
1106 void Adaptor::RenderOnce()
1107 {
1108   if(mThreadController)
1109   {
1110     UpdateMode updateMode;
1111     if(mThreadMode == ThreadMode::NORMAL)
1112     {
1113       updateMode = UpdateMode::NORMAL;
1114     }
1115     else
1116     {
1117       updateMode = UpdateMode::FORCE_RENDER;
1118
1119       ProcessCoreEvents();
1120     }
1121     mThreadController->RequestUpdateOnce(updateMode);
1122   }
1123 }
1124
1125 const LogFactoryInterface& Adaptor::GetLogFactory()
1126 {
1127   return *mEnvironmentOptions;
1128 }
1129
1130 void Adaptor::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
1131 {
1132   GetCore().RegisterProcessor(processor, postProcessor);
1133 }
1134
1135 void Adaptor::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
1136 {
1137   GetCore().UnregisterProcessor(processor, postProcessor);
1138 }
1139
1140 bool Adaptor::IsMultipleWindowSupported() const
1141 {
1142   return mConfigurationManager->IsMultipleWindowSupported();
1143 }
1144
1145 void Adaptor::RequestUpdateOnce()
1146 {
1147   if(mThreadController)
1148   {
1149     mThreadController->RequestUpdateOnce(UpdateMode::NORMAL);
1150   }
1151 }
1152
1153 bool Adaptor::ProcessCoreEventsFromIdle()
1154 {
1155   ProcessCoreEvents();
1156
1157   // the idle handle automatically un-installs itself
1158   mNotificationOnIdleInstalled = false;
1159
1160   return false;
1161 }
1162
1163 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow(Dali::Actor& actor)
1164 {
1165   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
1166
1167   for(auto window : mWindows)
1168   {
1169     if(scene == window->GetScene())
1170     {
1171       return window;
1172     }
1173   }
1174
1175   return nullptr;
1176 }
1177
1178 Dali::WindowContainer Adaptor::GetWindows() const
1179 {
1180   Dali::WindowContainer windows;
1181
1182   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1183   {
1184     // Downcast to Dali::Window
1185     Dali::Window window(dynamic_cast<Dali::Internal::Adaptor::Window*>(*iter));
1186     if(window)
1187     {
1188       windows.push_back(window);
1189     }
1190   }
1191
1192   return windows;
1193 }
1194
1195 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1196 {
1197   Dali::SceneHolderList sceneHolderList;
1198
1199   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1200   {
1201     sceneHolderList.push_back(Dali::Integration::SceneHolder(*iter));
1202   }
1203
1204   return sceneHolderList;
1205 }
1206
1207 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1208 {
1209   Dali::ObjectRegistry registry;
1210   if(mCore)
1211   {
1212     registry = mCore->GetObjectRegistry();
1213   }
1214   return registry;
1215 }
1216
1217 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
1218 : mResizedSignal(),
1219   mLanguageChangedSignal(),
1220   mWindowCreatedSignal(),
1221   mAdaptor(adaptor),
1222   mState(READY),
1223   mCore(nullptr),
1224   mThreadController(nullptr),
1225   mGraphics(nullptr),
1226   mDisplayConnection(nullptr),
1227   mWindows(),
1228   mConfigurationManager(nullptr),
1229   mPlatformAbstraction(nullptr),
1230   mCallbackManager(nullptr),
1231   mNotificationOnIdleInstalled(false),
1232   mNotificationTrigger(nullptr),
1233   mDaliFeedbackPlugin(),
1234   mFeedbackController(nullptr),
1235   mTtsPlayers(),
1236   mObservers(),
1237   mEnvironmentOptions(environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1238   mPerformanceInterface(nullptr),
1239   mKernelTracer(),
1240   mSystemTracer(),
1241   mObjectProfiler(nullptr),
1242   mMemoryPoolTimerSlotDelegate(this),
1243   mSocketFactory(),
1244   mMutex(),
1245   mThreadMode(threadMode),
1246   mEnvironmentOptionsOwned(environmentOptions ? false : true /* If not provided then we own the object */),
1247   mUseRemoteSurface(false),
1248   mRootLayoutDirection(Dali::LayoutDirection::LEFT_TO_RIGHT)
1249 {
1250   DALI_ASSERT_ALWAYS(!IsAvailable() && "Cannot create more than one Adaptor per thread");
1251   mWindows.insert(mWindows.begin(), &Dali::GetImplementation(window));
1252
1253   gThreadLocalAdaptor = this;
1254 }
1255
1256 void Adaptor::SetRootLayoutDirection(std::string locale)
1257 {
1258   mRootLayoutDirection = static_cast<LayoutDirection::Type>(Internal::Adaptor::Locale::GetDirection(std::string(locale)));
1259   for(auto& window : mWindows)
1260   {
1261     Dali::Actor root = window->GetRootLayer();
1262     root.SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
1263   }
1264 }
1265
1266 bool Adaptor::AddIdleEnterer(CallbackBase* callback, bool forceAdd)
1267 {
1268   bool idleAdded(false);
1269
1270   // Only add an idle if the Adaptor is actually running
1271   if(RUNNING == mState || READY == mState || forceAdd)
1272   {
1273     idleAdded = mCallbackManager->AddIdleEntererCallback(callback);
1274   }
1275
1276   if(!idleAdded)
1277   {
1278     // Delete callback
1279     delete callback;
1280   }
1281
1282   return idleAdded;
1283 }
1284
1285 void Adaptor::RemoveIdleEnterer(CallbackBase* callback)
1286 {
1287   mCallbackManager->RemoveIdleEntererCallback(callback);
1288 }
1289
1290 bool Adaptor::MemoryPoolTimeout()
1291 {
1292   mCore->LogMemoryPools();
1293   return true; // Keep logging forever
1294 }
1295
1296 } // namespace Adaptor
1297
1298 } // namespace Internal
1299
1300 } // namespace Dali