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