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