Adaptor checks its AddOnManager instance before operating on it.
[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
954   {
955     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
956   }
957 }
958
959 void Adaptor::OnWindowHidden()
960 {
961   if( RUNNING == mState || READY == mState )
962   {
963     bool allWindowsHidden = true;
964
965     for( auto window : mWindows )
966     {
967       if ( window->IsVisible() )
968       {
969         allWindowsHidden = false;
970         break;
971       }
972     }
973
974     // Only pause the adaptor when all the windows are hidden
975     if( allWindowsHidden )
976     {
977       if( mState == RUNNING )
978       {
979         Pause();
980
981         // Adaptor cannot be resumed until any window is shown
982         mState = PAUSED_WHILE_HIDDEN;
983       }
984       else  // mState is READY
985       {
986         // Pause the adaptor after the state gets RUNNING
987         mState = PAUSED_WHILE_INITIALIZING;
988       }
989     }
990     else
991     {
992       DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
993     }
994   }
995   else
996   {
997     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
998   }
999 }
1000
1001 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1002 void Adaptor::OnDamaged( const DamageArea& area )
1003 {
1004   // This is needed for the case where Dali window is partially obscured
1005   RequestUpdate( false );
1006 }
1007
1008 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1009 {
1010   mResizedSignal.Emit( mAdaptor );
1011 }
1012
1013 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1014 {
1015   // Nofify surface resizing before flushing event queue
1016   mThreadController->ResizeSurface();
1017
1018   // Flush the event queue to give the update-render thread chance
1019   // to start processing messages for new camera setup etc as soon as possible
1020   ProcessCoreEvents();
1021 }
1022
1023 void Adaptor::NotifySceneCreated()
1024 {
1025   GetCore().SceneCreated();
1026
1027   // Flush the event queue to give the update-render thread chance
1028   // to start processing messages for new camera setup etc as soon as possible
1029   ProcessCoreEvents();
1030
1031   // Start thread controller after the scene has been created
1032   mThreadController->Start();
1033
1034   // Process after surface is created (registering to remote surface provider if required)
1035   SurfaceInitialized();
1036
1037   if( mState != PAUSED_WHILE_INITIALIZING )
1038   {
1039     mState = RUNNING;
1040
1041     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1042   }
1043   else
1044   {
1045     mState = RUNNING;
1046
1047     Pause();
1048
1049     mState = PAUSED_WHILE_HIDDEN;
1050
1051     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1052   }
1053 }
1054
1055 void Adaptor::NotifyLanguageChanged()
1056 {
1057   mLanguageChangedSignal.Emit( mAdaptor );
1058 }
1059
1060 void Adaptor::RenderOnce()
1061 {
1062   if( mThreadController )
1063   {
1064     UpdateMode updateMode;
1065     if( mThreadMode == ThreadMode::NORMAL )
1066     {
1067       updateMode = UpdateMode::NORMAL;
1068     }
1069     else
1070     {
1071       updateMode = UpdateMode::FORCE_RENDER;
1072
1073       ProcessCoreEvents();
1074     }
1075     mThreadController->RequestUpdateOnce( updateMode );
1076   }
1077 }
1078
1079 const LogFactoryInterface& Adaptor::GetLogFactory()
1080 {
1081   return *mEnvironmentOptions;
1082 }
1083
1084 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1085 {
1086   GetCore().RegisterProcessor(processor);
1087 }
1088
1089 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1090 {
1091   GetCore().UnregisterProcessor(processor);
1092 }
1093
1094 bool Adaptor::IsMultipleWindowSupported() const
1095 {
1096   return mConfigurationManager->IsMultipleWindowSupported();
1097 }
1098
1099 void Adaptor::RequestUpdateOnce()
1100 {
1101   if( mThreadController )
1102   {
1103     mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1104   }
1105 }
1106
1107 bool Adaptor::ProcessCoreEventsFromIdle()
1108 {
1109   ProcessCoreEvents();
1110
1111   // the idle handle automatically un-installs itself
1112   mNotificationOnIdleInstalled = false;
1113
1114   return false;
1115 }
1116
1117 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1118 {
1119   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1120
1121   for( auto window : mWindows )
1122   {
1123     if ( scene == window->GetScene() )
1124     {
1125       return window;
1126     }
1127   }
1128
1129   return nullptr;
1130 }
1131
1132 Dali::WindowContainer Adaptor::GetWindows() const
1133 {
1134   Dali::WindowContainer windows;
1135
1136   for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1137   {
1138     // Downcast to Dali::Window
1139     Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1140     if ( window )
1141     {
1142       windows.push_back( window );
1143     }
1144   }
1145
1146   return windows;
1147 }
1148
1149 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1150 {
1151   Dali::SceneHolderList sceneHolderList;
1152
1153   for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1154   {
1155     sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1156   }
1157
1158   return sceneHolderList;
1159 }
1160
1161 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1162 {
1163   Dali::ObjectRegistry registry;
1164   if( mCore )
1165   {
1166     registry = mCore->GetObjectRegistry();
1167   }
1168   return registry;
1169 }
1170
1171 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1172 : mResizedSignal(),
1173   mLanguageChangedSignal(),
1174   mWindowCreatedSignal(),
1175   mAdaptor( adaptor ),
1176   mState( READY ),
1177   mCore( nullptr ),
1178   mThreadController( nullptr ),
1179   mGraphics( nullptr ),
1180   mDisplayConnection( nullptr ),
1181   mWindows(),
1182   mConfigurationManager( nullptr ),
1183   mPlatformAbstraction( nullptr ),
1184   mCallbackManager( nullptr ),
1185   mNotificationOnIdleInstalled( false ),
1186   mNotificationTrigger( nullptr ),
1187   mDaliFeedbackPlugin(),
1188   mFeedbackController( nullptr ),
1189   mTtsPlayers(),
1190   mObservers(),
1191   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1192   mPerformanceInterface( nullptr ),
1193   mKernelTracer(),
1194   mSystemTracer(),
1195   mObjectProfiler( nullptr ),
1196   mSocketFactory(),
1197   mThreadMode( ThreadMode::NORMAL ),
1198   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1199   mUseRemoteSurface( false )
1200 {
1201   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1202   mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1203
1204   gThreadLocalAdaptor = this;
1205 }
1206
1207 void Adaptor::SetRootLayoutDirection( std::string locale )
1208 {
1209   for ( auto& window : mWindows )
1210   {
1211     Dali::Actor root = window->GetRootLayer();
1212     root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1213                       static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1214   }
1215 }
1216
1217 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1218 {
1219   bool idleAdded( false );
1220
1221   // Only add an idle if the Adaptor is actually running
1222   if( RUNNING == mState || READY == mState || forceAdd )
1223   {
1224     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1225   }
1226
1227   if( !idleAdded )
1228   {
1229     // Delete callback
1230     delete callback;
1231   }
1232
1233   return idleAdded;
1234 }
1235
1236 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1237 {
1238   mCallbackManager->RemoveIdleEntererCallback( callback );
1239 }
1240
1241 } // namespace Adaptor
1242
1243 } // namespace Internal
1244
1245 } // namespace Dali