a9fbcfed0cc45b29f4aeeb2858e865a00d57c2ef
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
20 #include <dali/internal/adaptor/common/adaptor-impl.h>
21 #include <dali/internal/addons/common/addon-manager-factory.h>
22 #include <dali/internal/addons/common/addon-manager-impl.h>
23
24 // EXTERNAL INCLUDES
25 #include <dali/devel-api/actors/actor-devel.h>
26 #include <dali/devel-api/common/stage.h>
27 #include <dali/integration-api/addon-manager.h>
28 #include <dali/integration-api/context-notifier.h>
29 #include <dali/integration-api/core.h>
30 #include <dali/integration-api/debug.h>
31 #include <dali/integration-api/events/key-event-integ.h>
32 #include <dali/integration-api/events/touch-event-integ.h>
33 #include <dali/integration-api/events/wheel-event-integ.h>
34 #include <dali/integration-api/input-options.h>
35 #include <dali/integration-api/processor-interface.h>
36 #include <dali/integration-api/profiling.h>
37 #include <dali/integration-api/trace.h>
38 #include <dali/public-api/actors/layer.h>
39 #include <dali/public-api/events/wheel-event.h>
40 #include <dali/public-api/object/any.h>
41 #include <dali/public-api/object/object-registry.h>
42 #include <errno.h>
43 #include <sys/stat.h>
44
45 // INTERNAL INCLUDES
46 #include <dali/internal/adaptor/common/lifecycle-observer.h>
47 #include <dali/internal/adaptor/common/thread-controller-interface.h>
48 #include <dali/internal/system/common/performance-interface-factory.h>
49 #include <dali/internal/system/common/thread-controller.h>
50 #include <dali/public-api/dali-adaptor-common.h>
51
52 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
53 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
54
55 #include <dali/devel-api/text-abstraction/font-client.h>
56
57 #include <dali/internal/accessibility/common/tts-player-impl.h>
58 #include <dali/internal/clipboard/common/clipboard-impl.h>
59 #include <dali/internal/graphics/common/egl-image-extensions.h>
60 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
61 #include <dali/internal/graphics/gles/gl-implementation.h>
62 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
63 #include <dali/internal/system/common/callback-manager.h>
64 #include <dali/internal/system/common/object-profiler.h>
65 #include <dali/internal/window-system/common/display-connection.h>
66 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
67 #include <dali/internal/window-system/common/event-handler.h>
68 #include <dali/internal/window-system/common/window-impl.h>
69 #include <dali/internal/window-system/common/window-render-surface.h>
70
71 #include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
72 #include <dali/internal/system/common/logging.h>
73
74 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
75 #include <dali/internal/imaging/common/image-loader.h>
76 #include <dali/internal/system/common/locale-utils.h>
77
78 #include <dali/internal/system/common/configuration-manager.h>
79 #include <dali/internal/system/common/environment-variables.h>
80
81 using Dali::TextAbstraction::FontClient;
82
83 extern std::string GetSystemCachePath();
84
85 namespace Dali
86 {
87 namespace Internal
88 {
89 namespace Adaptor
90 {
91 namespace
92 {
93 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
94
95 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_PERFORMANCE_MARKER, false);
96 } // unnamed namespace
97
98 Dali::Adaptor* Adaptor::New(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
99 {
100   Dali::Adaptor* adaptor = new Dali::Adaptor;
101   Adaptor*       impl    = new Adaptor(window, *adaptor, surface, environmentOptions, threadMode);
102   adaptor->mImpl         = impl;
103
104   Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder(*(impl->mEnvironmentOptions));
105   auto                                     graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
106
107   impl->Initialize(graphicsFactory);
108   delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
109
110   return adaptor;
111 }
112
113 Dali::Adaptor* Adaptor::New(Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions)
114 {
115   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(window);
116   Dali::Adaptor*                  adaptor    = New(window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL);
117   windowImpl.SetAdaptor(*adaptor);
118   return adaptor;
119 }
120
121 Dali::Adaptor* Adaptor::New(GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
122 {
123   Dali::Adaptor* adaptor = new Dali::Adaptor;                                                      // Public adaptor
124   Adaptor*       impl    = new Adaptor(window, *adaptor, surface, environmentOptions, threadMode); // Impl adaptor
125   adaptor->mImpl         = impl;
126
127   impl->Initialize(graphicsFactory);
128
129   return adaptor;
130 } // Called second
131
132 Dali::Adaptor* Adaptor::New(GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions)
133 {
134   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(window);
135   Dali::Adaptor*                  adaptor    = New(graphicsFactory, window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL);
136   windowImpl.SetAdaptor(*adaptor);
137   return adaptor;
138 } // Called first
139
140 void Adaptor::Initialize(GraphicsFactory& graphicsFactory)
141 {
142   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
143   Dali::Integration::Log::LogFunction logFunction(Dali::TizenPlatform::LogMessage);
144   mEnvironmentOptions->SetLogFunction(logFunction);
145   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
146
147   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
148
149   std::string path;
150   GetDataStoragePath(path);
151   mPlatformAbstraction->SetDataStoragePath(path);
152
153   if(mEnvironmentOptions->PerformanceServerRequired())
154   {
155     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface(*this, *mEnvironmentOptions);
156   }
157
158   mEnvironmentOptions->CreateTraceManager(mPerformanceInterface);
159   mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
160
161   mCallbackManager = CallbackManager::New();
162
163   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
164
165   DALI_ASSERT_DEBUG(defaultWindow->GetSurface() && "Surface not initialized");
166
167   mGraphics = std::unique_ptr<GraphicsInterface>(&graphicsFactory.Create());
168
169   // Create the AddOnManager
170   mAddOnManager.reset(Dali::Internal::AddOnManagerFactory::CreateAddOnManager());
171
172   mCore = Integration::Core::New(*this,
173                                  *mPlatformAbstraction,
174                                  mGraphics->GetController(),
175                                  (0u != mEnvironmentOptions->GetRenderToFboInterval()) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
176                                  mGraphics->GetDepthBufferRequired(),
177                                  mGraphics->GetStencilBufferRequired(),
178                                  mGraphics->GetPartialUpdateRequired());
179
180   defaultWindow->SetAdaptor(Get());
181
182   Dali::Integration::SceneHolder defaultSceneHolder(defaultWindow);
183
184   mWindowCreatedSignal.Emit(defaultSceneHolder);
185
186   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
187   if(0u < timeInterval)
188   {
189     mObjectProfiler = new ObjectProfiler(mCore->GetObjectRegistry(), timeInterval);
190   }
191
192   mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &Adaptor::ProcessCoreEvents), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
193
194   mDisplayConnection = Dali::DisplayConnection::New(*mGraphics, defaultWindow->GetSurface()->GetSurfaceType());
195
196   mThreadController = new ThreadController(*this, *mEnvironmentOptions, mThreadMode);
197
198   // Should be called after Core creation
199   if(mEnvironmentOptions->GetPanGestureLoggingLevel())
200   {
201     Integration::EnableProfiling(Dali::Integration::PROFILING_TYPE_PAN_GESTURE);
202   }
203   if(mEnvironmentOptions->GetPanGesturePredictionMode() >= 0)
204   {
205     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
206   }
207   if(mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0)
208   {
209     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
210   }
211   if(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0)
212   {
213     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
214   }
215   if(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0)
216   {
217     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
218   }
219   if(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0)
220   {
221     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
222   }
223   if(mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0)
224   {
225     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
226   }
227   if(mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f)
228   {
229     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
230   }
231   if(mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0)
232   {
233     Integration::SetPanGestureUseActualTimes(mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false);
234   }
235   if(mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0)
236   {
237     Integration::SetPanGestureInterpolationTimeRange(mEnvironmentOptions->GetPanGestureInterpolationTimeRange());
238   }
239   if(mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0)
240   {
241     Integration::SetPanGestureScalarOnlyPredictionEnabled(mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false);
242   }
243   if(mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0)
244   {
245     Integration::SetPanGestureTwoPointPredictionEnabled(mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false);
246   }
247   if(mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0)
248   {
249     Integration::SetPanGestureTwoPointInterpolatePastTime(mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime());
250   }
251   if(mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f)
252   {
253     Integration::SetPanGestureTwoPointVelocityBias(mEnvironmentOptions->GetPanGestureTwoPointVelocityBias());
254   }
255   if(mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f)
256   {
257     Integration::SetPanGestureTwoPointAccelerationBias(mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias());
258   }
259   if(mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0)
260   {
261     Integration::SetPanGestureMultitapSmoothingRange(mEnvironmentOptions->GetPanGestureMultitapSmoothingRange());
262   }
263   if(mEnvironmentOptions->GetMinimumPanDistance() >= 0)
264   {
265     Integration::SetPanGestureMinimumDistance(mEnvironmentOptions->GetMinimumPanDistance());
266   }
267   if(mEnvironmentOptions->GetMinimumPanEvents() >= 0)
268   {
269     Integration::SetPanGestureMinimumPanEvents(mEnvironmentOptions->GetMinimumPanEvents());
270   }
271   if(mEnvironmentOptions->GetMinimumPinchDistance() >= 0)
272   {
273     Integration::SetPinchGestureMinimumDistance(mEnvironmentOptions->GetMinimumPinchDistance());
274   }
275   if(mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0)
276   {
277     Integration::SetPinchGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumPinchTouchEvents());
278   }
279   if(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0)
280   {
281     Integration::SetPinchGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart());
282   }
283   if(mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0)
284   {
285     Integration::SetRotationGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumRotationTouchEvents());
286   }
287   if(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0)
288   {
289     Integration::SetRotationGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart());
290   }
291   if(mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0)
292   {
293     Integration::SetLongPressMinimumHoldingTime(mEnvironmentOptions->GetLongPressMinimumHoldingTime());
294   }
295   if(mEnvironmentOptions->GetTapMaximumAllowedTime() > 0)
296   {
297     Integration::SetTapMaximumAllowedTime(mEnvironmentOptions->GetTapMaximumAllowedTime());
298   }
299
300   std::string systemCachePath = GetSystemCachePath();
301   if(!systemCachePath.empty())
302   {
303     const int dir_err = mkdir(systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
304     if(0 != dir_err && errno != EEXIST)
305     {
306       DALI_LOG_ERROR("Error creating system cache directory: %s!\n", systemCachePath.c_str());
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   {
679     Dali::Mutex::ScopedLock lock(mMutex);
680     mWindows.push_back(&windowImpl);
681   }
682
683   Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
684
685   mThreadController->AddSurface(surface);
686
687   mWindowCreatedSignal.Emit(childWindow);
688
689   return true;
690 }
691
692 bool Adaptor::RemoveWindow(Dali::Integration::SceneHolder* childWindow)
693 {
694   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(*childWindow);
695   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
696   {
697     if(*iter == &windowImpl)
698     {
699       Dali::Mutex::ScopedLock lock(mMutex);
700       mWindows.erase(iter);
701       return true;
702     }
703   }
704
705   return false;
706 }
707
708 bool Adaptor::RemoveWindow(std::string childWindowName)
709 {
710   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
711   {
712     if((*iter)->GetName() == childWindowName)
713     {
714       Dali::Mutex::ScopedLock lock(mMutex);
715       mWindows.erase(iter);
716       return true;
717     }
718   }
719
720   return false;
721 }
722
723 bool Adaptor::RemoveWindow(Internal::Adaptor::SceneHolder* childWindow)
724 {
725   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
726   {
727     if((*iter)->GetId() == childWindow->GetId())
728     {
729       Dali::Mutex::ScopedLock lock(mMutex);
730       mWindows.erase(iter);
731       return true;
732     }
733   }
734
735   return false;
736 }
737
738 Dali::Adaptor& Adaptor::Get()
739 {
740   DALI_ASSERT_ALWAYS(IsAvailable() && "Adaptor not instantiated");
741   return gThreadLocalAdaptor->mAdaptor;
742 }
743
744 bool Adaptor::IsAvailable()
745 {
746   return gThreadLocalAdaptor != NULL;
747 }
748
749 void Adaptor::SceneCreated()
750 {
751   mCore->SceneCreated();
752 }
753
754 Dali::Integration::Core& Adaptor::GetCore()
755 {
756   return *mCore;
757 }
758
759 void Adaptor::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender)
760 {
761   mThreadController->SetRenderRefreshRate(numberOfVSyncsPerRender);
762 }
763
764 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
765 {
766   DALI_ASSERT_DEBUG(mDisplayConnection && "Display connection not created");
767   return *mDisplayConnection;
768 }
769
770 GraphicsInterface& Adaptor::GetGraphicsInterface()
771 {
772   DALI_ASSERT_DEBUG(mGraphics && "Graphics interface not created");
773   return *(mGraphics.get());
774 }
775
776 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
777 {
778   return *mPlatformAbstraction;
779 }
780
781 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
782 {
783   return *mNotificationTrigger;
784 }
785
786 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
787 {
788   return mSocketFactory;
789 }
790
791 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
792 {
793   if(!mWindows.empty())
794   {
795     return mWindows.front()->GetSurface();
796   }
797
798   return nullptr;
799 }
800
801 TraceInterface& Adaptor::GetKernelTraceInterface()
802 {
803   return mKernelTracer;
804 }
805
806 TraceInterface& Adaptor::GetSystemTraceInterface()
807 {
808   return mSystemTracer;
809 }
810
811 PerformanceInterface* Adaptor::GetPerformanceInterface()
812 {
813   return mPerformanceInterface;
814 }
815
816 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
817 {
818   DALI_ASSERT_DEBUG(mPlatformAbstraction && "PlatformAbstraction not created");
819   return *mPlatformAbstraction;
820 }
821
822 void Adaptor::GetWindowContainerInterface(WindowContainer& windows)
823 {
824   Dali::Mutex::ScopedLock lock(mMutex);
825   windows = mWindows;
826 }
827
828 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
829 {
830   if(mTtsPlayers[mode])
831   {
832     mTtsPlayers[mode].Reset();
833   }
834 }
835
836 Any Adaptor::GetNativeWindowHandle()
837 {
838   return mWindows.front()->GetNativeHandle();
839 }
840
841 Any Adaptor::GetNativeWindowHandle(Dali::Actor actor)
842 {
843   Any nativeWindowHandle;
844
845   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
846
847   for(auto sceneHolder : mWindows)
848   {
849     if(scene == sceneHolder->GetScene())
850     {
851       nativeWindowHandle = sceneHolder->GetNativeHandle();
852       break;
853     }
854   }
855
856   return nativeWindowHandle;
857 }
858
859 Any Adaptor::GetGraphicsDisplay()
860 {
861   Any display;
862
863   if(mGraphics)
864   {
865     GraphicsInterface* graphics    = mGraphics.get(); // This interface is temporary until Core has been updated to match
866     auto               eglGraphics = static_cast<EglGraphics*>(graphics);
867
868     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
869     display                    = eglImpl.GetDisplay();
870   }
871
872   return display;
873 }
874
875 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
876 {
877   mUseRemoteSurface = useRemoteSurface;
878 }
879
880 void Adaptor::AddObserver(LifeCycleObserver& observer)
881 {
882   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
883
884   if(match == mObservers.end())
885   {
886     mObservers.push_back(&observer);
887   }
888 }
889
890 void Adaptor::RemoveObserver(LifeCycleObserver& observer)
891 {
892   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
893
894   if(match != mObservers.end())
895   {
896     mObservers.erase(match);
897   }
898 }
899
900 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
901 {
902   if(mCore)
903   {
904     mCore->QueueEvent(event);
905   }
906 }
907
908 void Adaptor::ProcessCoreEvents()
909 {
910   if(mCore)
911   {
912     if(mPerformanceInterface)
913     {
914       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_START);
915     }
916
917     DALI_TRACE_BEGIN(gTraceFilter, "DALI_PROCESS_CORE_EVENTS");
918
919     mCore->ProcessEvents();
920
921     DALI_TRACE_END(gTraceFilter, "DALI_PROCESS_CORE_EVENTS");
922
923     if(mPerformanceInterface)
924     {
925       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_END);
926     }
927   }
928 }
929
930 void Adaptor::RequestUpdate(bool forceUpdate)
931 {
932   switch(mState)
933   {
934     case RUNNING:
935     {
936       mThreadController->RequestUpdate();
937       break;
938     }
939     case PAUSED:
940     case PAUSED_WHILE_HIDDEN:
941     {
942       if(forceUpdate)
943       {
944         // Update (and resource upload) without rendering
945         mThreadController->RequestUpdateOnce(UpdateMode::SKIP_RENDER);
946       }
947       break;
948     }
949     default:
950     {
951       // Do nothing
952       break;
953     }
954   }
955 }
956
957 void Adaptor::RequestProcessEventsOnIdle(bool forceProcess)
958 {
959   // Only request a notification if the Adaptor is actually running
960   // and we haven't installed the idle notification
961   if((!mNotificationOnIdleInstalled) && (RUNNING == mState || READY == mState || forceProcess))
962   {
963     mNotificationOnIdleInstalled = AddIdleEnterer(MakeCallback(this, &Adaptor::ProcessCoreEventsFromIdle), forceProcess);
964   }
965 }
966
967 void Adaptor::OnWindowShown()
968 {
969   if(PAUSED_WHILE_HIDDEN == mState)
970   {
971     // Adaptor can now be resumed
972     mState = PAUSED;
973
974     Resume();
975
976     // Force a render task
977     RequestUpdateOnce();
978   }
979   else if(RUNNING == mState)
980   {
981     // Force a render task
982     RequestUpdateOnce();
983
984     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Update requested.\n");
985   }
986   else if(PAUSED_WHILE_INITIALIZING == mState)
987   {
988     // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
989     mState = READY;
990   }
991   else
992   {
993     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState);
994   }
995 }
996
997 void Adaptor::OnWindowHidden()
998 {
999   if(RUNNING == mState || READY == mState)
1000   {
1001     bool allWindowsHidden = true;
1002
1003     for(auto window : mWindows)
1004     {
1005       if(window->IsVisible())
1006       {
1007         allWindowsHidden = false;
1008         break;
1009       }
1010     }
1011
1012     // Only pause the adaptor when all the windows are hidden
1013     if(allWindowsHidden)
1014     {
1015       if(mState == RUNNING)
1016       {
1017         Pause();
1018
1019         // Adaptor cannot be resumed until any window is shown
1020         mState = PAUSED_WHILE_HIDDEN;
1021       }
1022       else // mState is READY
1023       {
1024         // Pause the adaptor after the state gets RUNNING
1025         mState = PAUSED_WHILE_INITIALIZING;
1026       }
1027     }
1028     else
1029     {
1030       DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n");
1031     }
1032   }
1033   else
1034   {
1035     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState);
1036   }
1037 }
1038
1039 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1040 void Adaptor::OnDamaged(const DamageArea& area)
1041 {
1042   // This is needed for the case where Dali window is partially obscured
1043   RequestUpdate(false);
1044 }
1045
1046 void Adaptor::SurfaceResizePrepare(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1047 {
1048   mResizedSignal.Emit(mAdaptor);
1049 }
1050
1051 void Adaptor::SurfaceResizeComplete(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1052 {
1053   // Nofify surface resizing before flushing event queue
1054   mThreadController->ResizeSurface();
1055
1056   // Flush the event queue to give the update-render thread chance
1057   // to start processing messages for new camera setup etc as soon as possible
1058   ProcessCoreEvents();
1059 }
1060
1061 void Adaptor::NotifySceneCreated()
1062 {
1063   GetCore().SceneCreated();
1064
1065   // Flush the event queue to give the update-render thread chance
1066   // to start processing messages for new camera setup etc as soon as possible
1067   ProcessCoreEvents();
1068
1069   // Start thread controller after the scene has been created
1070   mThreadController->Start();
1071
1072   // Process after surface is created (registering to remote surface provider if required)
1073   SurfaceInitialized();
1074
1075   if(mState != PAUSED_WHILE_INITIALIZING)
1076   {
1077     mState = RUNNING;
1078
1079     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is running\n");
1080   }
1081   else
1082   {
1083     mState = RUNNING;
1084
1085     Pause();
1086
1087     mState = PAUSED_WHILE_HIDDEN;
1088
1089     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is paused\n");
1090   }
1091 }
1092
1093 void Adaptor::NotifyLanguageChanged()
1094 {
1095   mLanguageChangedSignal.Emit(mAdaptor);
1096 }
1097
1098 void Adaptor::RenderOnce()
1099 {
1100   if(mThreadController)
1101   {
1102     UpdateMode updateMode;
1103     if(mThreadMode == ThreadMode::NORMAL)
1104     {
1105       updateMode = UpdateMode::NORMAL;
1106     }
1107     else
1108     {
1109       updateMode = UpdateMode::FORCE_RENDER;
1110
1111       ProcessCoreEvents();
1112     }
1113     mThreadController->RequestUpdateOnce(updateMode);
1114   }
1115 }
1116
1117 const LogFactoryInterface& Adaptor::GetLogFactory()
1118 {
1119   return *mEnvironmentOptions;
1120 }
1121
1122 void Adaptor::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
1123 {
1124   GetCore().RegisterProcessor(processor, postProcessor);
1125 }
1126
1127 void Adaptor::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
1128 {
1129   GetCore().UnregisterProcessor(processor, postProcessor);
1130 }
1131
1132 bool Adaptor::IsMultipleWindowSupported() const
1133 {
1134   return mConfigurationManager->IsMultipleWindowSupported();
1135 }
1136
1137 void Adaptor::RequestUpdateOnce()
1138 {
1139   if(mThreadController)
1140   {
1141     mThreadController->RequestUpdateOnce(UpdateMode::NORMAL);
1142   }
1143 }
1144
1145 bool Adaptor::ProcessCoreEventsFromIdle()
1146 {
1147   ProcessCoreEvents();
1148
1149   // the idle handle automatically un-installs itself
1150   mNotificationOnIdleInstalled = false;
1151
1152   return false;
1153 }
1154
1155 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow(Dali::Actor& actor)
1156 {
1157   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
1158
1159   for(auto window : mWindows)
1160   {
1161     if(scene == window->GetScene())
1162     {
1163       return window;
1164     }
1165   }
1166
1167   return nullptr;
1168 }
1169
1170 Dali::WindowContainer Adaptor::GetWindows() const
1171 {
1172   Dali::WindowContainer windows;
1173
1174   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1175   {
1176     // Downcast to Dali::Window
1177     Dali::Window window(dynamic_cast<Dali::Internal::Adaptor::Window*>(*iter));
1178     if(window)
1179     {
1180       windows.push_back(window);
1181     }
1182   }
1183
1184   return windows;
1185 }
1186
1187 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1188 {
1189   Dali::SceneHolderList sceneHolderList;
1190
1191   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1192   {
1193     sceneHolderList.push_back(Dali::Integration::SceneHolder(*iter));
1194   }
1195
1196   return sceneHolderList;
1197 }
1198
1199 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1200 {
1201   Dali::ObjectRegistry registry;
1202   if(mCore)
1203   {
1204     registry = mCore->GetObjectRegistry();
1205   }
1206   return registry;
1207 }
1208
1209 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
1210 : mResizedSignal(),
1211   mLanguageChangedSignal(),
1212   mWindowCreatedSignal(),
1213   mAdaptor(adaptor),
1214   mState(READY),
1215   mCore(nullptr),
1216   mThreadController(nullptr),
1217   mGraphics(nullptr),
1218   mDisplayConnection(nullptr),
1219   mWindows(),
1220   mConfigurationManager(nullptr),
1221   mPlatformAbstraction(nullptr),
1222   mCallbackManager(nullptr),
1223   mNotificationOnIdleInstalled(false),
1224   mNotificationTrigger(nullptr),
1225   mDaliFeedbackPlugin(),
1226   mFeedbackController(nullptr),
1227   mTtsPlayers(),
1228   mObservers(),
1229   mEnvironmentOptions(environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1230   mPerformanceInterface(nullptr),
1231   mKernelTracer(),
1232   mSystemTracer(),
1233   mObjectProfiler(nullptr),
1234   mSocketFactory(),
1235   mMutex(),
1236   mThreadMode(threadMode),
1237   mEnvironmentOptionsOwned(environmentOptions ? false : true /* If not provided then we own the object */),
1238   mUseRemoteSurface(false),
1239   mRootLayoutDirection(Dali::LayoutDirection::LEFT_TO_RIGHT)
1240 {
1241   DALI_ASSERT_ALWAYS(!IsAvailable() && "Cannot create more than one Adaptor per thread");
1242   mWindows.insert(mWindows.begin(), &Dali::GetImplementation(window));
1243
1244   gThreadLocalAdaptor = this;
1245 }
1246
1247 void Adaptor::SetRootLayoutDirection(std::string locale)
1248 {
1249   mRootLayoutDirection = static_cast<LayoutDirection::Type>(Internal::Adaptor::Locale::GetDirection(std::string(locale)));
1250   for(auto& window : mWindows)
1251   {
1252     Dali::Actor root = window->GetRootLayer();
1253     root.SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
1254   }
1255 }
1256
1257 bool Adaptor::AddIdleEnterer(CallbackBase* callback, bool forceAdd)
1258 {
1259   bool idleAdded(false);
1260
1261   // Only add an idle if the Adaptor is actually running
1262   if(RUNNING == mState || READY == mState || forceAdd)
1263   {
1264     idleAdded = mCallbackManager->AddIdleEntererCallback(callback);
1265   }
1266
1267   if(!idleAdded)
1268   {
1269     // Delete callback
1270     delete callback;
1271   }
1272
1273   return idleAdded;
1274 }
1275
1276 void Adaptor::RemoveIdleEnterer(CallbackBase* callback)
1277 {
1278   mCallbackManager->RemoveIdleEntererCallback(callback);
1279 }
1280
1281 } // namespace Adaptor
1282
1283 } // namespace Internal
1284
1285 } // namespace Dali