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