Trace use scope macro instead of begin-end
[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     DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_CORE_EVENTS");
921
922     if(mPerformanceInterface)
923     {
924       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_START);
925     }
926
927     mCore->ProcessEvents();
928
929     if(mPerformanceInterface)
930     {
931       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_END);
932     }
933   }
934 }
935
936 void Adaptor::RequestUpdate(bool forceUpdate)
937 {
938   switch(mState)
939   {
940     case RUNNING:
941     {
942       mThreadController->RequestUpdate();
943       break;
944     }
945     case PAUSED:
946     case PAUSED_WHILE_HIDDEN:
947     {
948       if(forceUpdate)
949       {
950         // Update (and resource upload) without rendering
951         mThreadController->RequestUpdateOnce(UpdateMode::SKIP_RENDER);
952       }
953       break;
954     }
955     default:
956     {
957       // Do nothing
958       break;
959     }
960   }
961 }
962
963 void Adaptor::RequestProcessEventsOnIdle(bool forceProcess)
964 {
965   // Only request a notification if the Adaptor is actually running
966   // and we haven't installed the idle notification
967   if((!mNotificationOnIdleInstalled) && (RUNNING == mState || READY == mState || forceProcess))
968   {
969     mNotificationOnIdleInstalled = AddIdleEnterer(MakeCallback(this, &Adaptor::ProcessCoreEventsFromIdle), forceProcess);
970   }
971 }
972
973 void Adaptor::OnWindowShown()
974 {
975   if(PAUSED_WHILE_HIDDEN == mState)
976   {
977     // Adaptor can now be resumed
978     mState = PAUSED;
979
980     Resume();
981
982     // Force a render task
983     RequestUpdateOnce();
984   }
985   else if(RUNNING == mState)
986   {
987     // Force a render task
988     RequestUpdateOnce();
989
990     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Update requested.\n");
991   }
992   else if(PAUSED_WHILE_INITIALIZING == mState)
993   {
994     // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
995     mState = READY;
996   }
997   else
998   {
999     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState);
1000   }
1001 }
1002
1003 void Adaptor::OnWindowHidden()
1004 {
1005   if(RUNNING == mState || READY == mState)
1006   {
1007     bool allWindowsHidden = true;
1008
1009     for(auto window : mWindows)
1010     {
1011       if(window->IsVisible())
1012       {
1013         allWindowsHidden = false;
1014         break;
1015       }
1016     }
1017
1018     // Only pause the adaptor when all the windows are hidden
1019     if(allWindowsHidden)
1020     {
1021       if(mState == RUNNING)
1022       {
1023         Pause();
1024
1025         // Adaptor cannot be resumed until any window is shown
1026         mState = PAUSED_WHILE_HIDDEN;
1027       }
1028       else // mState is READY
1029       {
1030         // Pause the adaptor after the state gets RUNNING
1031         mState = PAUSED_WHILE_INITIALIZING;
1032       }
1033     }
1034     else
1035     {
1036       DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n");
1037     }
1038   }
1039   else
1040   {
1041     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState);
1042   }
1043 }
1044
1045 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1046 void Adaptor::OnDamaged(const DamageArea& area)
1047 {
1048   // This is needed for the case where Dali window is partially obscured
1049   RequestUpdate(false);
1050 }
1051
1052 void Adaptor::SurfaceResizePrepare(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1053 {
1054   mResizedSignal.Emit(mAdaptor);
1055 }
1056
1057 void Adaptor::SurfaceResizeComplete(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1058 {
1059   // Nofify surface resizing before flushing event queue
1060   mThreadController->ResizeSurface();
1061
1062   // Flush the event queue to give the update-render thread chance
1063   // to start processing messages for new camera setup etc as soon as possible
1064   ProcessCoreEvents();
1065 }
1066
1067 void Adaptor::NotifySceneCreated()
1068 {
1069   GetCore().SceneCreated();
1070
1071   // Flush the event queue to give the update-render thread chance
1072   // to start processing messages for new camera setup etc as soon as possible
1073   ProcessCoreEvents();
1074
1075   // Start thread controller after the scene has been created
1076   mThreadController->Start();
1077
1078   // Process after surface is created (registering to remote surface provider if required)
1079   SurfaceInitialized();
1080
1081   if(mState != PAUSED_WHILE_INITIALIZING)
1082   {
1083     mState = RUNNING;
1084
1085     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is running\n");
1086   }
1087   else
1088   {
1089     mState = RUNNING;
1090
1091     Pause();
1092
1093     mState = PAUSED_WHILE_HIDDEN;
1094
1095     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is paused\n");
1096   }
1097 }
1098
1099 void Adaptor::NotifyLanguageChanged()
1100 {
1101   mLanguageChangedSignal.Emit(mAdaptor);
1102 }
1103
1104 void Adaptor::RenderOnce()
1105 {
1106   if(mThreadController)
1107   {
1108     UpdateMode updateMode;
1109     if(mThreadMode == ThreadMode::NORMAL)
1110     {
1111       updateMode = UpdateMode::NORMAL;
1112     }
1113     else
1114     {
1115       updateMode = UpdateMode::FORCE_RENDER;
1116
1117       ProcessCoreEvents();
1118     }
1119     mThreadController->RequestUpdateOnce(updateMode);
1120   }
1121 }
1122
1123 const LogFactoryInterface& Adaptor::GetLogFactory()
1124 {
1125   return *mEnvironmentOptions;
1126 }
1127
1128 void Adaptor::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
1129 {
1130   GetCore().RegisterProcessor(processor, postProcessor);
1131 }
1132
1133 void Adaptor::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
1134 {
1135   GetCore().UnregisterProcessor(processor, postProcessor);
1136 }
1137
1138 bool Adaptor::IsMultipleWindowSupported() const
1139 {
1140   return mConfigurationManager->IsMultipleWindowSupported();
1141 }
1142
1143 void Adaptor::RequestUpdateOnce()
1144 {
1145   if(mThreadController)
1146   {
1147     mThreadController->RequestUpdateOnce(UpdateMode::NORMAL);
1148   }
1149 }
1150
1151 bool Adaptor::ProcessCoreEventsFromIdle()
1152 {
1153   ProcessCoreEvents();
1154
1155   // the idle handle automatically un-installs itself
1156   mNotificationOnIdleInstalled = false;
1157
1158   return false;
1159 }
1160
1161 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow(Dali::Actor& actor)
1162 {
1163   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
1164
1165   for(auto window : mWindows)
1166   {
1167     if(scene == window->GetScene())
1168     {
1169       return window;
1170     }
1171   }
1172
1173   return nullptr;
1174 }
1175
1176 Dali::WindowContainer Adaptor::GetWindows() const
1177 {
1178   Dali::WindowContainer windows;
1179
1180   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1181   {
1182     // Downcast to Dali::Window
1183     Dali::Window window(dynamic_cast<Dali::Internal::Adaptor::Window*>(*iter));
1184     if(window)
1185     {
1186       windows.push_back(window);
1187     }
1188   }
1189
1190   return windows;
1191 }
1192
1193 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1194 {
1195   Dali::SceneHolderList sceneHolderList;
1196
1197   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1198   {
1199     sceneHolderList.push_back(Dali::Integration::SceneHolder(*iter));
1200   }
1201
1202   return sceneHolderList;
1203 }
1204
1205 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1206 {
1207   Dali::ObjectRegistry registry;
1208   if(mCore)
1209   {
1210     registry = mCore->GetObjectRegistry();
1211   }
1212   return registry;
1213 }
1214
1215 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
1216 : mResizedSignal(),
1217   mLanguageChangedSignal(),
1218   mWindowCreatedSignal(),
1219   mAdaptor(adaptor),
1220   mState(READY),
1221   mCore(nullptr),
1222   mThreadController(nullptr),
1223   mGraphics(nullptr),
1224   mDisplayConnection(nullptr),
1225   mWindows(),
1226   mConfigurationManager(nullptr),
1227   mPlatformAbstraction(nullptr),
1228   mCallbackManager(nullptr),
1229   mNotificationOnIdleInstalled(false),
1230   mNotificationTrigger(nullptr),
1231   mDaliFeedbackPlugin(),
1232   mFeedbackController(nullptr),
1233   mTtsPlayers(),
1234   mObservers(),
1235   mEnvironmentOptions(environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1236   mPerformanceInterface(nullptr),
1237   mKernelTracer(),
1238   mSystemTracer(),
1239   mObjectProfiler(nullptr),
1240   mMemoryPoolTimerSlotDelegate(this),
1241   mSocketFactory(),
1242   mMutex(),
1243   mThreadMode(threadMode),
1244   mEnvironmentOptionsOwned(environmentOptions ? false : true /* If not provided then we own the object */),
1245   mUseRemoteSurface(false),
1246   mRootLayoutDirection(Dali::LayoutDirection::LEFT_TO_RIGHT)
1247 {
1248   DALI_ASSERT_ALWAYS(!IsAvailable() && "Cannot create more than one Adaptor per thread");
1249   mWindows.insert(mWindows.begin(), &Dali::GetImplementation(window));
1250
1251   gThreadLocalAdaptor = this;
1252 }
1253
1254 void Adaptor::SetRootLayoutDirection(std::string locale)
1255 {
1256   mRootLayoutDirection = static_cast<LayoutDirection::Type>(Internal::Adaptor::Locale::GetDirection(std::string(locale)));
1257   for(auto& window : mWindows)
1258   {
1259     Dali::Actor root = window->GetRootLayer();
1260     root.SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
1261   }
1262 }
1263
1264 bool Adaptor::AddIdleEnterer(CallbackBase* callback, bool forceAdd)
1265 {
1266   bool idleAdded(false);
1267
1268   // Only add an idle if the Adaptor is actually running
1269   if(RUNNING == mState || READY == mState || forceAdd)
1270   {
1271     idleAdded = mCallbackManager->AddIdleEntererCallback(callback);
1272   }
1273
1274   if(!idleAdded)
1275   {
1276     // Delete callback
1277     delete callback;
1278   }
1279
1280   return idleAdded;
1281 }
1282
1283 void Adaptor::RemoveIdleEnterer(CallbackBase* callback)
1284 {
1285   mCallbackManager->RemoveIdleEntererCallback(callback);
1286 }
1287
1288 bool Adaptor::MemoryPoolTimeout()
1289 {
1290   mCore->LogMemoryPools();
1291   return true; // Keep logging forever
1292 }
1293
1294 } // namespace Adaptor
1295
1296 } // namespace Internal
1297
1298 } // namespace Dali