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