Merge branch 'devel/master' into tizen_6.5
[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   if(mEnvironmentOptions->GetTapMaximumAllowedTime() > 0)
294   {
295     Integration::SetTapMaximumAllowedTime(mEnvironmentOptions->GetTapMaximumAllowedTime());
296   }
297
298
299   std::string systemCachePath = GetSystemCachePath();
300   if(!systemCachePath.empty())
301   {
302     const int dir_err = mkdir(systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
303     if(0 != dir_err && errno != EEXIST)
304     {
305       DALI_LOG_ERROR("Error creating system cache directory: %s!\n", systemCachePath.c_str());
306       exit(1);
307     }
308   }
309
310   mConfigurationManager = Utils::MakeUnique<ConfigurationManager>(systemCachePath, mGraphics.get(), mThreadController);
311 }
312
313 void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent(const Dali::KeyEvent& event)
314 {
315   Accessibility::KeyEventType type;
316   if(event.GetState() == Dali::KeyEvent::DOWN)
317   {
318     type = Accessibility::KeyEventType::KEY_PRESSED;
319   }
320   else if(event.GetState() == Dali::KeyEvent::UP)
321   {
322     type = Accessibility::KeyEventType::KEY_RELEASED;
323   }
324   else
325   {
326     return;
327   }
328   Dali::Accessibility::Bridge::GetCurrentBridge()->Emit(type, event.GetKeyCode(), event.GetKeyName(), event.GetTime(), !event.GetKeyString().empty());
329 }
330
331 Adaptor::~Adaptor()
332 {
333   Accessibility::Bridge::GetCurrentBridge()->Terminate();
334
335   // Ensure stop status
336   Stop();
337
338   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
339   gThreadLocalAdaptor = NULL;
340
341   for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
342   {
343     (*iter)->OnDestroy();
344   }
345
346   // Clear out all the handles to Windows
347   mWindows.clear();
348
349   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
350   delete mObjectProfiler;
351
352   delete mCore;
353
354   delete mDisplayConnection;
355   delete mPlatformAbstraction;
356   delete mCallbackManager;
357   delete mPerformanceInterface;
358
359   mGraphics->Destroy();
360
361   // uninstall it on this thread (main actor thread)
362   Dali::Integration::Log::UninstallLogFunction();
363
364   // Delete environment options if we own it
365   if(mEnvironmentOptionsOwned)
366   {
367     delete mEnvironmentOptions;
368   }
369 }
370
371 void Adaptor::Start()
372 {
373   // It doesn't support restart after stop at this moment to support restarting, need more testing
374   if(READY != mState)
375   {
376     return;
377   }
378
379   mCore->Initialize();
380
381   SetupSystemInformation();
382
383   // Start the callback manager
384   mCallbackManager->Start();
385
386   // Initialize accessibility bridge after callback manager is started to use Idler callback
387   auto appName = GetApplicationPackageName();
388   auto bridge  = Accessibility::Bridge::GetCurrentBridge();
389   bridge->SetApplicationName(appName);
390   bridge->Initialize();
391   Dali::Stage::GetCurrent().KeyEventSignal().Connect(&mAccessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent);
392
393   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
394
395   unsigned int dpiHor, dpiVer;
396   dpiHor = dpiVer = 0;
397
398   defaultWindow->GetSurface()->GetDpi(dpiHor, dpiVer);
399
400   // set the DPI value for font rendering
401   FontClient fontClient = FontClient::Get();
402   fontClient.SetDpi(dpiHor, dpiVer);
403
404   // Initialize the thread controller
405   mThreadController->Initialize();
406
407   // Set max texture size
408   if(mEnvironmentOptions->GetMaxTextureSize() > 0)
409   {
410     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(mEnvironmentOptions->GetMaxTextureSize());
411   }
412   else
413   {
414     unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
415     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(maxTextureSize);
416   }
417
418   // cache advanced blending and shader language version
419   mGraphics->CacheConfigurations(*mConfigurationManager.get());
420
421   ProcessCoreEvents(); // Ensure any startup messages are processed.
422
423   // Initialize the image loader plugin
424   Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
425
426   for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
427   {
428     (*iter)->OnStart();
429   }
430
431   if(mAddOnManager)
432   {
433     mAddOnManager->Start();
434   }
435 }
436
437 // Dali::Internal::Adaptor::Adaptor::Pause
438 void Adaptor::Pause()
439 {
440   // Only pause the adaptor if we're actually running.
441   if(RUNNING == mState)
442   {
443     // Inform observers that we are about to be paused.
444     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
445     {
446       (*iter)->OnPause();
447     }
448
449     // Extensions
450     if(mAddOnManager)
451     {
452       mAddOnManager->Pause();
453     }
454
455     // Pause all windows event handlers when adaptor paused
456     for(auto window : mWindows)
457     {
458       window->Pause();
459     }
460
461     mThreadController->Pause();
462     mState = PAUSED;
463
464     // Ensure any messages queued during pause callbacks are processed by doing another update.
465     RequestUpdateOnce();
466
467     DALI_LOG_RELEASE_INFO("Adaptor::Pause: Paused\n");
468   }
469   else
470   {
471     DALI_LOG_RELEASE_INFO("Adaptor::Pause: Not paused [%d]\n", mState);
472   }
473 }
474
475 // Dali::Internal::Adaptor::Adaptor::Resume
476 void Adaptor::Resume()
477 {
478   // Only resume the adaptor if we are in the suspended state.
479   if(PAUSED == mState)
480   {
481     mState = RUNNING;
482
483     // Reset the event handlers when adaptor resumed
484     for(auto window : mWindows)
485     {
486       window->Resume();
487     }
488
489     // Resume AddOnManager
490     if(mAddOnManager)
491     {
492       mAddOnManager->Resume();
493     }
494
495     // Inform observers that we have resumed.
496     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
497     {
498       (*iter)->OnResume();
499     }
500
501     // Trigger processing of events queued up while paused
502     mCore->ProcessEvents();
503
504     // Do at end to ensure our first update/render after resumption includes the processed messages as well
505     mThreadController->Resume();
506
507     DALI_LOG_RELEASE_INFO("Adaptor::Resume: Resumed\n");
508   }
509   else
510   {
511     DALI_LOG_RELEASE_INFO("Adaptor::Resume: Not resumed [%d]\n", mState);
512   }
513 }
514
515 void Adaptor::Stop()
516 {
517   if(RUNNING == mState ||
518      PAUSED == mState ||
519      PAUSED_WHILE_HIDDEN == mState)
520   {
521     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
522     {
523       (*iter)->OnStop();
524     }
525
526     if(mAddOnManager)
527     {
528       mAddOnManager->Stop();
529     }
530
531     mThreadController->Stop();
532
533     // Delete the TTS player
534     for(int i = 0; i < Dali::TtsPlayer::MODE_NUM; i++)
535     {
536       if(mTtsPlayers[i])
537       {
538         mTtsPlayers[i].Reset();
539       }
540     }
541
542     // Destroy the image loader plugin
543     Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
544
545     delete mNotificationTrigger;
546     mNotificationTrigger = NULL;
547
548     mCallbackManager->Stop();
549
550     mState = STOPPED;
551
552     DALI_LOG_RELEASE_INFO("Adaptor::Stop\n");
553   }
554 }
555
556 void Adaptor::ContextLost()
557 {
558   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
559 }
560
561 void Adaptor::ContextRegained()
562 {
563   // Inform core, so that texture resources can be reloaded
564   mCore->RecoverFromContextLoss();
565
566   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
567 }
568
569 void Adaptor::FeedTouchPoint(TouchPoint& point, int timeStamp)
570 {
571   Integration::Point convertedPoint(point);
572   mWindows.front()->FeedTouchPoint(convertedPoint, timeStamp);
573 }
574
575 void Adaptor::FeedWheelEvent(Dali::WheelEvent& wheelEvent)
576 {
577   Integration::WheelEvent event(static_cast<Integration::WheelEvent::Type>(wheelEvent.GetType()), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime());
578   mWindows.front()->FeedWheelEvent(event);
579 }
580
581 void Adaptor::FeedKeyEvent(Dali::KeyEvent& keyEvent)
582 {
583   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());
584   mWindows.front()->FeedKeyEvent(convertedEvent);
585 }
586
587 void Adaptor::ReplaceSurface(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface)
588 {
589   Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation(window);
590   for(auto windowPtr : mWindows)
591   {
592     if(windowPtr == windowImpl) // the window is not deleted
593     {
594       mResizedSignal.Emit(mAdaptor);
595
596       windowImpl->SetSurface(&newSurface);
597
598       // Flush the event queue to give the update-render thread chance
599       // to start processing messages for new camera setup etc as soon as possible
600       ProcessCoreEvents();
601
602       // This method blocks until the render thread has completed the replace.
603       mThreadController->ReplaceSurface(&newSurface);
604       break;
605     }
606   }
607 }
608
609 void Adaptor::DeleteSurface(Dali::RenderSurfaceInterface& surface)
610 {
611   // Flush the event queue to give the update-render thread chance
612   // to start processing messages for new camera setup etc as soon as possible
613   ProcessCoreEvents();
614
615   // This method blocks until the render thread has finished rendering the current surface.
616   mThreadController->DeleteSurface(&surface);
617 }
618
619 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
620 {
621   return *mWindows.front()->GetSurface();
622 }
623
624 void Adaptor::ReleaseSurfaceLock()
625 {
626   mWindows.front()->GetSurface()->ReleaseLock();
627 }
628
629 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
630 {
631   if(!mTtsPlayers[mode])
632   {
633     // Create the TTS player when it needed, because it can reduce launching time.
634     mTtsPlayers[mode] = TtsPlayer::New(mode);
635   }
636
637   return mTtsPlayers[mode];
638 }
639
640 bool Adaptor::AddIdle(CallbackBase* callback, bool hasReturnValue, bool forceAdd)
641 {
642   bool idleAdded(false);
643
644   // Only add an idle if the Adaptor is actually running
645   if(RUNNING == mState || READY == mState || forceAdd)
646   {
647     idleAdded = mCallbackManager->AddIdleCallback(callback, hasReturnValue);
648   }
649
650   return idleAdded;
651 }
652
653 void Adaptor::RemoveIdle(CallbackBase* callback)
654 {
655   mCallbackManager->RemoveIdleCallback(callback);
656 }
657
658 void Adaptor::ProcessIdle()
659 {
660   bool idleProcessed           = mCallbackManager->ProcessIdle();
661   mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
662 }
663
664 void Adaptor::SetPreRenderCallback(CallbackBase* callback)
665 {
666   mThreadController->SetPreRenderCallback(callback);
667 }
668
669 bool Adaptor::AddWindow(Dali::Integration::SceneHolder childWindow)
670 {
671   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(childWindow);
672   windowImpl.SetAdaptor(Get());
673
674   // ChildWindow is set to the layout direction of the default window.
675   windowImpl.GetRootLayer().SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
676
677   // Add the new Window to the container - the order is not important
678   mWindows.push_back(&windowImpl);
679
680   Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
681
682   mThreadController->AddSurface(surface);
683
684   mWindowCreatedSignal.Emit(childWindow);
685
686   return true;
687 }
688
689 bool Adaptor::RemoveWindow(Dali::Integration::SceneHolder* childWindow)
690 {
691   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(*childWindow);
692   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
693   {
694     if(*iter == &windowImpl)
695     {
696       mWindows.erase(iter);
697       return true;
698     }
699   }
700
701   return false;
702 }
703
704 bool Adaptor::RemoveWindow(std::string childWindowName)
705 {
706   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
707   {
708     if((*iter)->GetName() == childWindowName)
709     {
710       mWindows.erase(iter);
711       return true;
712     }
713   }
714
715   return false;
716 }
717
718 bool Adaptor::RemoveWindow(Internal::Adaptor::SceneHolder* childWindow)
719 {
720   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
721   {
722     if((*iter)->GetId() == childWindow->GetId())
723     {
724       mWindows.erase(iter);
725       return true;
726     }
727   }
728
729   return false;
730 }
731
732 Dali::Adaptor& Adaptor::Get()
733 {
734   DALI_ASSERT_ALWAYS(IsAvailable() && "Adaptor not instantiated");
735   return gThreadLocalAdaptor->mAdaptor;
736 }
737
738 bool Adaptor::IsAvailable()
739 {
740   return gThreadLocalAdaptor != NULL;
741 }
742
743 void Adaptor::SceneCreated()
744 {
745   mCore->SceneCreated();
746 }
747
748 Dali::Integration::Core& Adaptor::GetCore()
749 {
750   return *mCore;
751 }
752
753 void Adaptor::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender)
754 {
755   mThreadController->SetRenderRefreshRate(numberOfVSyncsPerRender);
756 }
757
758 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
759 {
760   DALI_ASSERT_DEBUG(mDisplayConnection && "Display connection not created");
761   return *mDisplayConnection;
762 }
763
764 GraphicsInterface& Adaptor::GetGraphicsInterface()
765 {
766   DALI_ASSERT_DEBUG(mGraphics && "Graphics interface not created");
767   return *(mGraphics.get());
768 }
769
770 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
771 {
772   return *mPlatformAbstraction;
773 }
774
775 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
776 {
777   return *mNotificationTrigger;
778 }
779
780 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
781 {
782   return mSocketFactory;
783 }
784
785 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
786 {
787   if(!mWindows.empty())
788   {
789     return mWindows.front()->GetSurface();
790   }
791
792   return nullptr;
793 }
794
795 TraceInterface& Adaptor::GetKernelTraceInterface()
796 {
797   return mKernelTracer;
798 }
799
800 TraceInterface& Adaptor::GetSystemTraceInterface()
801 {
802   return mSystemTracer;
803 }
804
805 PerformanceInterface* Adaptor::GetPerformanceInterface()
806 {
807   return mPerformanceInterface;
808 }
809
810 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
811 {
812   DALI_ASSERT_DEBUG(mPlatformAbstraction && "PlatformAbstraction not created");
813   return *mPlatformAbstraction;
814 }
815
816 void Adaptor::GetWindowContainerInterface(WindowContainer& windows)
817 {
818   windows = mWindows;
819 }
820
821 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
822 {
823   if(mTtsPlayers[mode])
824   {
825     mTtsPlayers[mode].Reset();
826   }
827 }
828
829 Any Adaptor::GetNativeWindowHandle()
830 {
831   return mWindows.front()->GetNativeHandle();
832 }
833
834 Any Adaptor::GetNativeWindowHandle(Dali::Actor actor)
835 {
836   Any nativeWindowHandle;
837
838   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
839
840   for(auto sceneHolder : mWindows)
841   {
842     if(scene == sceneHolder->GetScene())
843     {
844       nativeWindowHandle = sceneHolder->GetNativeHandle();
845       break;
846     }
847   }
848
849   return nativeWindowHandle;
850 }
851
852 Any Adaptor::GetGraphicsDisplay()
853 {
854   Any display;
855
856   if(mGraphics)
857   {
858     GraphicsInterface* graphics    = mGraphics.get(); // This interface is temporary until Core has been updated to match
859     auto               eglGraphics = static_cast<EglGraphics*>(graphics);
860
861     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
862     display                    = eglImpl.GetDisplay();
863   }
864
865   return display;
866 }
867
868 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
869 {
870   mUseRemoteSurface = useRemoteSurface;
871 }
872
873 void Adaptor::AddObserver(LifeCycleObserver& observer)
874 {
875   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
876
877   if(match == mObservers.end())
878   {
879     mObservers.push_back(&observer);
880   }
881 }
882
883 void Adaptor::RemoveObserver(LifeCycleObserver& observer)
884 {
885   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
886
887   if(match != mObservers.end())
888   {
889     mObservers.erase(match);
890   }
891 }
892
893 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
894 {
895   if(mCore)
896   {
897     mCore->QueueEvent(event);
898   }
899 }
900
901 void Adaptor::ProcessCoreEvents()
902 {
903   if(mCore)
904   {
905     if(mPerformanceInterface)
906     {
907       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_START);
908     }
909
910     mCore->ProcessEvents();
911
912     if(mPerformanceInterface)
913     {
914       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_END);
915     }
916   }
917 }
918
919 void Adaptor::RequestUpdate(bool forceUpdate)
920 {
921   switch(mState)
922   {
923     case RUNNING:
924     {
925       mThreadController->RequestUpdate();
926       break;
927     }
928     case PAUSED:
929     case PAUSED_WHILE_HIDDEN:
930     {
931       if(forceUpdate)
932       {
933         // Update (and resource upload) without rendering
934         mThreadController->RequestUpdateOnce(UpdateMode::SKIP_RENDER);
935       }
936       break;
937     }
938     default:
939     {
940       // Do nothing
941       break;
942     }
943   }
944 }
945
946 void Adaptor::RequestProcessEventsOnIdle(bool forceProcess)
947 {
948   // Only request a notification if the Adaptor is actually running
949   // and we haven't installed the idle notification
950   if((!mNotificationOnIdleInstalled) && (RUNNING == mState || READY == mState || forceProcess))
951   {
952     mNotificationOnIdleInstalled = AddIdleEnterer(MakeCallback(this, &Adaptor::ProcessCoreEventsFromIdle), forceProcess);
953   }
954 }
955
956 void Adaptor::OnWindowShown()
957 {
958   if(PAUSED_WHILE_HIDDEN == mState)
959   {
960     // Adaptor can now be resumed
961     mState = PAUSED;
962
963     Resume();
964
965     // Force a render task
966     RequestUpdateOnce();
967   }
968   else if(RUNNING == mState)
969   {
970     // Force a render task
971     RequestUpdateOnce();
972
973     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Update requested.\n");
974   }
975   else if(PAUSED_WHILE_INITIALIZING == mState)
976   {
977     // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
978     mState = READY;
979   }
980   else
981   {
982     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState);
983   }
984 }
985
986 void Adaptor::OnWindowHidden()
987 {
988   if(RUNNING == mState || READY == mState)
989   {
990     bool allWindowsHidden = true;
991
992     for(auto window : mWindows)
993     {
994       if(window->IsVisible())
995       {
996         allWindowsHidden = false;
997         break;
998       }
999     }
1000
1001     // Only pause the adaptor when all the windows are hidden
1002     if(allWindowsHidden)
1003     {
1004       if(mState == RUNNING)
1005       {
1006         Pause();
1007
1008         // Adaptor cannot be resumed until any window is shown
1009         mState = PAUSED_WHILE_HIDDEN;
1010       }
1011       else // mState is READY
1012       {
1013         // Pause the adaptor after the state gets RUNNING
1014         mState = PAUSED_WHILE_INITIALIZING;
1015       }
1016     }
1017     else
1018     {
1019       DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n");
1020     }
1021   }
1022   else
1023   {
1024     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState);
1025   }
1026 }
1027
1028 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1029 void Adaptor::OnDamaged(const DamageArea& area)
1030 {
1031   // This is needed for the case where Dali window is partially obscured
1032   RequestUpdate(false);
1033 }
1034
1035 void Adaptor::SurfaceResizePrepare(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1036 {
1037   mResizedSignal.Emit(mAdaptor);
1038 }
1039
1040 void Adaptor::SurfaceResizeComplete(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1041 {
1042   // Nofify surface resizing before flushing event queue
1043   mThreadController->ResizeSurface();
1044
1045   // Flush the event queue to give the update-render thread chance
1046   // to start processing messages for new camera setup etc as soon as possible
1047   ProcessCoreEvents();
1048 }
1049
1050 void Adaptor::NotifySceneCreated()
1051 {
1052   GetCore().SceneCreated();
1053
1054   // Flush the event queue to give the update-render thread chance
1055   // to start processing messages for new camera setup etc as soon as possible
1056   ProcessCoreEvents();
1057
1058   // Start thread controller after the scene has been created
1059   mThreadController->Start();
1060
1061   // Process after surface is created (registering to remote surface provider if required)
1062   SurfaceInitialized();
1063
1064   if(mState != PAUSED_WHILE_INITIALIZING)
1065   {
1066     mState = RUNNING;
1067
1068     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is running\n");
1069   }
1070   else
1071   {
1072     mState = RUNNING;
1073
1074     Pause();
1075
1076     mState = PAUSED_WHILE_HIDDEN;
1077
1078     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is paused\n");
1079   }
1080 }
1081
1082 void Adaptor::NotifyLanguageChanged()
1083 {
1084   mLanguageChangedSignal.Emit(mAdaptor);
1085 }
1086
1087 void Adaptor::RenderOnce()
1088 {
1089   if(mThreadController)
1090   {
1091     UpdateMode updateMode;
1092     if(mThreadMode == ThreadMode::NORMAL)
1093     {
1094       updateMode = UpdateMode::NORMAL;
1095     }
1096     else
1097     {
1098       updateMode = UpdateMode::FORCE_RENDER;
1099
1100       ProcessCoreEvents();
1101     }
1102     mThreadController->RequestUpdateOnce(updateMode);
1103   }
1104 }
1105
1106 const LogFactoryInterface& Adaptor::GetLogFactory()
1107 {
1108   return *mEnvironmentOptions;
1109 }
1110
1111 void Adaptor::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
1112 {
1113   GetCore().RegisterProcessor(processor, postProcessor);
1114 }
1115
1116 void Adaptor::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
1117 {
1118   GetCore().UnregisterProcessor(processor, postProcessor);
1119 }
1120
1121 bool Adaptor::IsMultipleWindowSupported() const
1122 {
1123   return mConfigurationManager->IsMultipleWindowSupported();
1124 }
1125
1126 void Adaptor::RequestUpdateOnce()
1127 {
1128   if(mThreadController)
1129   {
1130     mThreadController->RequestUpdateOnce(UpdateMode::NORMAL);
1131   }
1132 }
1133
1134 bool Adaptor::ProcessCoreEventsFromIdle()
1135 {
1136   ProcessCoreEvents();
1137
1138   // the idle handle automatically un-installs itself
1139   mNotificationOnIdleInstalled = false;
1140
1141   return false;
1142 }
1143
1144 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow(Dali::Actor& actor)
1145 {
1146   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
1147
1148   for(auto window : mWindows)
1149   {
1150     if(scene == window->GetScene())
1151     {
1152       return window;
1153     }
1154   }
1155
1156   return nullptr;
1157 }
1158
1159 Dali::WindowContainer Adaptor::GetWindows() const
1160 {
1161   Dali::WindowContainer windows;
1162
1163   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1164   {
1165     // Downcast to Dali::Window
1166     Dali::Window window(dynamic_cast<Dali::Internal::Adaptor::Window*>(*iter));
1167     if(window)
1168     {
1169       windows.push_back(window);
1170     }
1171   }
1172
1173   return windows;
1174 }
1175
1176 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1177 {
1178   Dali::SceneHolderList sceneHolderList;
1179
1180   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1181   {
1182     sceneHolderList.push_back(Dali::Integration::SceneHolder(*iter));
1183   }
1184
1185   return sceneHolderList;
1186 }
1187
1188 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1189 {
1190   Dali::ObjectRegistry registry;
1191   if(mCore)
1192   {
1193     registry = mCore->GetObjectRegistry();
1194   }
1195   return registry;
1196 }
1197
1198 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
1199 : mResizedSignal(),
1200   mLanguageChangedSignal(),
1201   mWindowCreatedSignal(),
1202   mAdaptor(adaptor),
1203   mState(READY),
1204   mCore(nullptr),
1205   mThreadController(nullptr),
1206   mGraphics(nullptr),
1207   mDisplayConnection(nullptr),
1208   mWindows(),
1209   mConfigurationManager(nullptr),
1210   mPlatformAbstraction(nullptr),
1211   mCallbackManager(nullptr),
1212   mNotificationOnIdleInstalled(false),
1213   mNotificationTrigger(nullptr),
1214   mDaliFeedbackPlugin(),
1215   mFeedbackController(nullptr),
1216   mTtsPlayers(),
1217   mObservers(),
1218   mEnvironmentOptions(environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1219   mPerformanceInterface(nullptr),
1220   mKernelTracer(),
1221   mSystemTracer(),
1222   mObjectProfiler(nullptr),
1223   mSocketFactory(),
1224   mThreadMode(threadMode),
1225   mEnvironmentOptionsOwned(environmentOptions ? false : true /* If not provided then we own the object */),
1226   mUseRemoteSurface(false),
1227   mRootLayoutDirection(Dali::LayoutDirection::LEFT_TO_RIGHT)
1228 {
1229   DALI_ASSERT_ALWAYS(!IsAvailable() && "Cannot create more than one Adaptor per thread");
1230   mWindows.insert(mWindows.begin(), &Dali::GetImplementation(window));
1231
1232   gThreadLocalAdaptor = this;
1233 }
1234
1235 void Adaptor::SetRootLayoutDirection(std::string locale)
1236 {
1237   mRootLayoutDirection = static_cast<LayoutDirection::Type>(Internal::Adaptor::Locale::GetDirection(std::string(locale)));
1238   for(auto& window : mWindows)
1239   {
1240     Dali::Actor root = window->GetRootLayer();
1241     root.SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
1242   }
1243 }
1244
1245 bool Adaptor::AddIdleEnterer(CallbackBase* callback, bool forceAdd)
1246 {
1247   bool idleAdded(false);
1248
1249   // Only add an idle if the Adaptor is actually running
1250   if(RUNNING == mState || READY == mState || forceAdd)
1251   {
1252     idleAdded = mCallbackManager->AddIdleEntererCallback(callback);
1253   }
1254
1255   if(!idleAdded)
1256   {
1257     // Delete callback
1258     delete callback;
1259   }
1260
1261   return idleAdded;
1262 }
1263
1264 void Adaptor::RemoveIdleEnterer(CallbackBase* callback)
1265 {
1266   mCallbackManager->RemoveIdleEntererCallback(callback);
1267 }
1268
1269 } // namespace Adaptor
1270
1271 } // namespace Internal
1272
1273 } // namespace Dali