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