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